jq:将字段从对象数组提升到父对象

时间:2019-01-14 19:13:42

标签: json jq

我在顶层有一个数组的JSON对象,每个数组条目都是一个对象,其中嵌套对象数组是字段之一。 我想将某些字段从子数组“提升”到第一个数组中的对象中。写起来很混乱,所以这是我的输入:

{ "emails": [
  { "email":"foo1@bar.com",
    "events":[
      { "type":"open", "time":"t1", "ignore":"this" },
      { "type":"click", "time":"t2", "ignore":"this" } ] },
  { "email":"foo2@bar.com",
    "events":[
      { "type":"open", "time":"t3", "ignore":"this" },
      { "type":"click", "time":"t4", "ignore":"this" },
      { "type":"open", "time":"t5", "ignore":"this" } ] }
] }

我希望收到的输出是:

[
  { "email":"foo1@bar.com", "type":"open", "time":"t1" },
  { "email":"foo1@bar.com", "type":"click", "time":"t2" },
  { "email":"foo2@bar.com", "type":"open", "time":"t3" },
  { "email":"foo2@bar.com", "type":"click", "time":"t4" },
  { "email":"foo2@bar.com", "type":"open", "time":"t5" }
]

我可以jq已经有多个管道了,就像这样:

 [ .emails[] | { email:.email, event:(.events[] | { type:.type, time:.time }) } | { email:.email, type:.event.type, time:.event.time } ]

...但这似乎太冗长了。 是否有一种更简单的方法将那些typetime字段从最深的对象“提升”到一个更高的对象? 当我尝试两次使用.events[]迭代器时,最后看到事件的笛卡尔积,这是错误的:-/

要实现这一目标,我必须缺少一种更简单的方法(比我上面的“中间对象”方法)……有人知道更好的方法吗?

1 个答案:

答案 0 :(得分:0)

让我们分两步进行:首先,(重)提升,然后,(轻)修剪。

升降

.emails | map( {email}  + .events[])

或等效地:

[.emails[] | {email}  + .events[]]

请注意,{"email": .email}已缩写为{email}

修剪

我们可以使用del(.ignore)删除“忽略”键。着眼于效率,我们得出以下解决方案:

.emails | map( {email}  + (.events[] | del(.ignore) )