JQ 过滤嵌套对象中的字段

Posted

技术标签:

【中文标题】JQ 过滤嵌套对象中的字段【英文标题】:JQ filtering on fields in nested Objects 【发布时间】:2018-06-05 09:12:21 【问题描述】:

我有一大组数据,我正在使用 JQ 构造对象,该对象仅包含我感兴趣的数据作为记录。我的问题是我开始看到重复的对象,看来我的语法不正确。

我正在处理一个包含平面字段和子对象数组的对象,我想要提取特定字段并创建具有我想要的所有数据的新对象。包括一些平面字段和数组对象中的一些字段。

这是一个较小的示例,有助于演示问题tmpData.json


"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batter": [
        "id": "1001",
        "type": "Regular"
    ,
    
        "id": "1002",
        "type": "Chocolate"
    ,
    
        "id": "1003",
        "type": "Blueberry"
    ,
    
        "id": "1004",
        "type": "Devil's Food"
    
]

我运行这个:cat tmpData.txt | jq 'id: .id, type: .type, batter: .batter[].id'

输出这个非 json 对象集(缺少逗号)


  "id": "0001",
  "type": "donut",
  "batter": "1001"


  "id": "0001",
  "type": "donut",
  "batter": "1002"


  "id": "0001",
  "type": "donut",
  "batter": "1003"


  "id": "0001",
  "type": "donut",
  "batter": "1004"

这很好。我现在有对象,每个对象都包含 parentID 0001,并且数组中的不同项目在每个对象中关联。

当我跑步时:cat tmpData.txt | jq 'id: .id, type: .type, batterID: .batter[].id, batterType: .batter[].type'

添加 type 字段后,我得到了很多错误地关联项目的重复项


  "id": "0001",
  "type": "donut",
  "batterID": "1001",
  "batterType": "Regular"


  "id": "0001",
  "type": "donut",
  "batterID": "1001",
  "batterType": "Chocolate"


  "id": "0001",
  "type": "donut",
  "batterID": "1001",
  "batterType": "Blueberry"


  "id": "0001",
  "type": "donut",
  "batterID": "1001",
  "batterType": "Devil's Food"


  "id": "0001",
  "type": "donut",
  "batterID": "1002",
  "batterType": "Regular"


  "id": "0001",
  "type": "donut",
  "batterID": "1002",
  "batterType": "Chocolate"


  "id": "0001",
  "type": "donut",
  "batterID": "1002",
  "batterType": "Blueberry"


  "id": "0001",
  "type": "donut",
  "batterID": "1002",
  "batterType": "Devil's Food"


  "id": "0001",
  "type": "donut",
  "batterID": "1003",
  "batterType": "Regular"


  "id": "0001",
  "type": "donut",
  "batterID": "1003",
  "batterType": "Chocolate"


  "id": "0001",
  "type": "donut",
  "batterID": "1003",
  "batterType": "Blueberry"


  "id": "0001",
  "type": "donut",
  "batterID": "1003",
  "batterType": "Devil's Food"


  "id": "0001",
  "type": "donut",
  "batterID": "1004",
  "batterType": "Regular"


  "id": "0001",
  "type": "donut",
  "batterID": "1004",
  "batterType": "Chocolate"


  "id": "0001",
  "type": "donut",
  "batterID": "1004",
  "batterType": "Blueberry"


  "id": "0001",
  "type": "donut",
  "batterID": "1004",
  "batterType": "Devil's Food"

现在我看到每个batterID 都在一个具有每种类型regular, chocolate, blueberry 的对象中。但实际上1002 永远只是chocolate

我的理想输出是这样的

 [
"id": "0001",
"type": "donut",
"batterID": "1001",
"batterType": "Regular"
,

"id": "0001",
"type": "donut",
"batterID": "1002",
"batterType": "Chocolate"
] 

感谢您的专业知识!

编辑已解决:工作命令:cat tmpData.txt | jq '[id, type + (.batter[] | batterId: .id, batterType: .type)]'

【问题讨论】:

【参考方案1】:
    “不带逗号”的输出是 JSON 流;要发出一个数组,请将您的 jq 过滤器放在方括号中。 您可以将id: id, type: .type缩写为id, type 重复 .batter[] 的过滤器具有创建笛卡尔积的效果。你显然想要什么 而是只扩展 .batter 一次。

把所有东西放在一起:

[id, type + (.batter[] | batterId: .id, batterType: .type)]

【讨论】:

我收到错误-bash: syntax error near unexpected token `(' 你能用JQ 命令展示一下吗? @峰 尝试将 jq 程序放在一个文件中,比如 program.jq,并使用 -f 选项调用 jq,例如jq -f program.jq tmpData.json 原来只是我需要将整个 JQ 命令用单引号括起来。请参阅编辑。谢谢!!

以上是关于JQ 过滤嵌套对象中的字段的主要内容,如果未能解决你的问题,请参考以下文章

带有 C#Driver 的 MongoDB:如何过滤嵌套对象数组中的字段

没有无限过滤链的JQ对象选择

搜索字段:过滤嵌套对象

jq streaming - 过滤嵌套列表并保留全局结构

如何使用jq根据内部数组中的值过滤对象数组?

JQ:过滤键