【问题标题】:jq join on common keyjq 加入公共密钥
【发布时间】:2021-09-10 14:47:16
【问题描述】:

我对@9​​87654321@ 很陌生,这篇文章是由于不了解jq 背后的机制造成的。 我可以开发一个 bash 脚本,它可以满足我的需求,但是 jq 和它的 JSON 超级大国引起了我的兴趣,我想通过应用到现实世界的场景中来学习它。这是一个...

顺便说一句,我尝试利用现有的 jq 相关 SO 解决方案来合并/加入 JSON,但失败了。

最接近我需要的是使用 INDEX 和 $x + 的串联。 ,但是我只从我的第二个 (c2) json 获得了最后一个项目。

所以,我的问题如下:

有两个JSON 文件:

  • JSON #1 将具有唯一的“id”和“type”键 - 以及其他键/值对,为了使帖子更清晰,我已将其删除。

  • JSON #2 将包含多个/非唯一“类型”键,我想匹配这两个 JSON 文件。这个JSON #2 还将包含其他键/值对,预计将包含在结果输出中。

我的输出要求是: 我想获得 c1 和 c2 数组之间匹配键/值对的所有组合的(每行一个或单个数组)列表,其中“类型”键(字符串)的值在 c1 和 c2 之间完全匹配。

还有一个问题,扩展解决方案以同时在三个JSON 文件之间执行类似的匹配/连接——再次在特定键的相同值上执行,难度有多大?

任何帮助,甚至只是提示如何解决和理解如何解决这个问题都将不胜感激!

第一个输入文件:JSON #1,数组 c1(集合 1)

{ "c1":
[
{ "c1id":1, "type":"alpha" },
{ "c1id":2, "type":"beta" }
]
}

第二个输入文件:JSON #2, Array c2 (collection 2)

{
"c2":
[
{ "c2id":1,"type":"alpha","serial":"DDBB001"} ,
{ "c2id":2,"type":"beta","serial":"DDBB007"} ,
{ "c2id":3,"type":"alpha","serial":"DDTT005"} ,
{ "c2id":4,"type":"beta","serial":"DDAA002"} ,
{ "c2id":5,"type":"yotta","serial":"DDCC017"}
]
}

预期输出:

{"c1id":1,"type":"alpha","c2id":1,"serial":"DDBB001"}
{"c1id":1,"type":"alpha","c2id":3,"serial":"DDTT005"}
{"c1id":2,"type":"beta","c2id":2,"serial":"DDBB007"}
{"c1id":2,"type":"beta","c2id":4,"serial":"DDAA002"} 

您会注意到输出中不包含 c2 中的类型“yotta”。这是意料之中的。只有存在于 c1 和匹配 c2 的“类型”才会出现在结果中。我想这是一个匹配/加入练习暗示的 - 我添加它只是为了清楚起见 - 我希望它有效。

【问题讨论】:

  • 为什么{"c2id":5,"type":"yotta","serial":"DDCC017"} 不能匹配{ "c1id":3, "type":"yotta" }?好像都是同一种类型?
  • 你是对的。这是我的遗漏,我将从 c1 中删除该行。道歉。

标签: json join merge jq


【解决方案1】:

这是一个使用 INDEX 和 JOIN 的示例:

jq --compact-output --slurpfile c1 c1.json '
    INDEX(
        $c1[0].c1[];
        .type
    ) as $index |
    JOIN(
        $index;
        .c2[];
        .type;
        reverse|add
    )
' c2.json

INDEX 的第一个参数需要产生一个项目流,这就是为什么我们应用[] 来分别从数组中获取项目。第二个参数选择我们的索引键。

我们使用 JOIN 的四参数版本。第一个参数是索引本身,第二个是要连接到索引的对象流,第三个参数从流式对象中选择查找键,第四个参数是组合连接对象的表达式。该表达式的输入是一个包含两项的数组流,每个数组看起来像这样:

[{"c2id":1,"type":"alpha","serial":"DDBB001"},{"c1id":1,"type":"alpha"}]

因为我们只想组合来自对象的所有键和值,所以我们只使用add,但我们首先使用reverse 数组来很好地将 c1 字段排列在 c2 字段之前。最终结果如你所愿:

{"c1id":1,"type":"alpha","c2id":1,"serial":"DDBB001"}
{"c1id":2,"type":"beta","c2id":2,"serial":"DDBB007"}
{"c1id":1,"type":"alpha","c2id":3,"serial":"DDTT005"}
{"c1id":2,"type":"beta","c2id":4,"serial":"DDAA002"}

【讨论】:

  • 对于遇到这个问题的每个人来说,使用的函数是文档中 SQL-Style 参数下详述的内置函数。这是 jq 上最热门的答案之一
猜你喜欢
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 2019-06-24
  • 2013-04-06
相关资源
最近更新 更多