如何将处理大型JSON文件的jq查询转换为流式查询?
处理大型JSON数组的流式jq查询方案
直接用常规jq查询2.7GB的JSON数组会因内存限制失败,改用jq的流式解析模式就能解决问题,具体改造如下:
核心改造思路
jq的--stream参数会把JSON拆分成路径-值对的流,避免一次性加载整个文件到内存。我们需要筛选出数组元素对应的流条目,还原成单个对象后再应用你原来的字段筛选逻辑。
改造后的查询代码
fromstream(1|truncate_stream(inputs | select(.[0][0] != null))) | { food: .foodClass, description: .description, foodNutrients: [.foodNutrients[] | { nutrients: .nutrient, amount: .amount}], upc: .gtinUpc, servingSize: .servingSize, servingSizeUnit: .servingSizeUnit, ingredients: .ingredients, fdcId: .fdcId, dataType: .dataType, brandOwner: .brandOwner, marketCountry: .marketCountry, brandedFootCategory: .brandedFoodCategory }
关键参数说明
--stream:开启流式解析模式,逐块读取输入文件。-n:配合inputs使用,告诉jq不要自动读取整个输入,而是通过inputs处理流式数据。select(.[0][0] != null):过滤掉数组结束的标记条目,只保留数组元素的相关数据。1|truncate_stream:移除路径中的数组索引部分,让fromstream能把每个元素的流条目还原成完整对象。
完整执行命令
把上述查询保存到filter.jq文件,然后执行:
jq --stream -n -f filter.jq large_file.json > output.json
如果不想用文件,直接在命令行执行:
jq --stream -n 'fromstream(1|truncate_stream(inputs | select(.[0][0] != null))) | {food: .foodClass, description: .description, foodNutrients: [.foodNutrients[] | { nutrients: .nutrient, amount: .amount}], upc: .gtinUpc, servingSize: .servingSize, servingSizeUnit: .servingSizeUnit, ingredients: .ingredients, fdcId: .fdcId, dataType: .dataType, brandOwner: .brandOwner, marketCountry: .marketCountry, brandedFootCategory: .brandedFoodCategory}' large_file.json > output.json
内容的提问来源于stack exchange,提问作者Aaron Jackson
相关产品推荐
相关产品推荐

