如何通过公共键值对合并JSON?基于jq工具的技术问询
解决方案:用jq基于deviceId合并嵌套JSON文档
我正好处理过类似的JSON合并需求,用jq可以很优雅地实现。核心思路是先把bar.json转换为以deviceId为键的映射表,这样就能快速查找对应设备的a字段,再把它合并到foo.json的Schedule数组元素中。
具体命令
假设你已经安装了jq(推荐1.6及以上版本,包含便捷的INDEX函数),可以直接运行:
jq --argfile bar bar.json ' # 将bar数组转换为deviceId -> 对应对象的映射 ($bar | INDEX(.deviceId)) as $deviceMap # 更新Schedule数组,为每个元素添加对应的a字段 | .Schedule |= map(. + ($deviceMap[.deviceId] | {a})) ' foo.json > foobar.json
命令解释
--argfile bar bar.json:把bar.json的内容加载到jq变量$bar中,方便后续处理。($bar | INDEX(.deviceId)):利用jq的INDEX函数,将bar数组转换为一个键值对对象,键是每个元素的deviceId值,值是对应的完整对象。这一步是为了实现O(1)时间复杂度的查找,比遍历数组高效得多。.Schedule |= map(...):使用|=操作符更新原JSON的Schedule字段,遍历数组中的每个元素进行修改。. + ($deviceMap[.deviceId] | {a}):将当前Schedule元素与从映射表中取出的对应设备的a字段合并。{a}确保我们只提取需要的字段,避免重复添加deviceId(虽然重复也不影响JSON解析,但这样更严谨)。
兼容旧版jq(低于1.6)
如果你的jq版本没有INDEX函数,可以用reduce手动构建映射表:
jq --argfile bar bar.json ' ($bar | reduce .[] as $item ({}; .[$item.deviceId] = $item)) as $deviceMap | .Schedule |= map(. + ($deviceMap[.deviceId] | {a})) ' foo.json > foobar.json
验证结果
运行命令后,输出的foobar.json结构会完全符合你的期望:每个Schedule元素保留原有字段的同时,新增了对应设备的a嵌套对象,原有的serverTime字段也会完整保留。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

