使用ijson解析16GB大JSON文件时遇IncompleteJSONError求助
解决ijson解析含MongoDB扩展语法JSON文件的IncompleteJSONError问题
问题根源
你遇到的IncompleteJSONError是因为目标JSON文件使用了MongoDB的非标准JSON扩展语法(比如NumberInt(0)),而ijson是严格遵循标准JSON规范的解析库,无法识别这类语法。从你提供的JSON片段可以看到,venue.type、year、n_citation等字段都使用了NumberInt()包裹数字,这就是报错的直接原因。
解决方案
由于文件体积达16GB,无法一次性加载到内存修改,我们需要流式处理:一边读取文件内容,一边替换MongoDB的非标准语法为标准JSON格式,再交给ijson解析。
代码实现
下面是针对大文件的流式修复+解析方案,无需加载整个文件到内存:
import ijson import re # 自定义类文件对象,流式修复MongoDB扩展语法 class MongoJSONFixer: def __init__(self, file_obj): self.file_obj = file_obj # 正则匹配NumberInt/NumberLong格式,可根据需要扩展 self.pattern = re.compile(b'(NumberInt|NumberLong)\\((\\d+)\\)') def read(self, size=-1): # 按需读取文件块,替换非标准语法后返回 chunk = self.file_obj.read(size) return self.pattern.sub(b'\\2', chunk) # 解析修复后的JSON paper_id_tab = [] with open("dblpv13.json", "rb") as f: # 包装原始文件对象,自动修复语法 fixed_file = MongoJSONFixer(f) # 注意:这里的路径'records.item'需要和你的JSON顶层结构匹配 # 如果JSON根是直接的数组,改为'item'即可 for record in ijson.items(fixed_file, 'records.item', use_float=True): paper_id = record["_id"] paper_id_tab.append(paper_id)
补充说明
- 如果你的JSON文件还包含其他MongoDB扩展(比如
ObjectId("xxx")、ISODate("xxx")),可以扩展正则表达式来处理,例如添加匹配规则替换为标准字符串格式。 - 确认
ijson.items的第二个参数路径是否正确:如果你的JSON顶层结构是{"records": [ {...}, {...} ]},则用'records.item';如果是直接的数组[ {...}, {...} ],则用'item'。
内容的提问来源于stack exchange,提问作者red ben
相关产品推荐
相关产品推荐

