3

免责声明:确实,已经有不同的答案(例如JQ Join JSON files by keydenormalizing JSON with jq),但它们都没有帮助我,或者确实有不同的情况我无法从中得出解决方案;/


我有 2 个文件,它们都是对象列表,其中一个具有对另一个对象 ID 的字段引用

给定

[
  {
    "id": "5b9f50ccdcdf200283f29052",
    "reference": {
      "id": "5de82d5072f4a72ad5d5dcc1"
    }
  }
]

[
  {
    "id": "5de82d5072f4a72ad5d5dcc1",
    "name": "FooBar"
  }
]

我的目标是获得一个非规范化的对象列表:

预期的

[
  {
    "id": "5b9f50ccdcdf200283f29052",
    "reference": {
      "id": "5de82d5072f4a72ad5d5dcc1",
      "name": "FooBar"
    }
  }
]

虽然我能够完成主要部分,但我还没有挑战将两者结合在一起:

示例 1

jq -s '(.[1][] | select(.id == "5de82d5072f4a72ad5d5dcc1"))' objects.json referredObjects.json

我明白了

{
  "id": "5de82d5072f4a72ad5d5dcc1",
  "name": "FooBar"
}

并以 示例2

jq -s '.[0][] | .reference = {}' objects.json referredObjects.json

我可以操纵任何.reference获取

{
  "id": "5b9f50ccdcdf200283f29052",
  "reference": {}
}

(即使我失去了列表结构)

但是:我不能做某事。喜欢

执行“加入”

jq -s '.[0][] as $obj | $obj.reference = (.[1][] | select(.id == $obj.reference.id))' objects.json referredObjects.json

甚至接近foreachreduce看起来很有希望

jq -s '[foreach .[0][] as $obj ({}; .reference.id = ""; . + $obj )]' objects.json referredObjects.json

=>

[
  {
    "reference": {
      "id": "5de82d5072f4a72ad5d5dcc1"
    },
    "id": "5b9f50ccdcdf200283f29052"
  }
]

我希望得到与第二个示例相同的地方

我最终感到头疼,并期待用任何语言写一个无效的例行程序......希望我会感谢任何帮助

〜马塞尔

4

2 回答 2

3

将第二个文件转换为 ID 和名称配对的对象,并在更新第一个文件时将其用作参考。

$ jq '(map({(.id): .}) | add) as $idx
      | input
      | map_values(.reference = $idx[.reference.id])' file2 file1
[
  {
    "id": "5b9f50ccdcdf200283f29052",
    "reference": {
      "id": "5de82d5072f4a72ad5d5dcc1",
      "name": "FooBar"
    }
  }
]
于 2020-02-26T12:18:09.007 回答
2

以下解决方案使用与@OguzIsmail 在解决方案中使用的策略相同的策略,但使用内置函数INDEX/2从第二个文件构造字典。

重要的一点是,此策略允许两个文件中的数组为任意大小。

调用

jq --argfile file2 file2.json -f program.jq file1.json

程序.jq

INDEX($file2[]; .id) as $dict
| map(.reference.id as $id | .reference = $dict[$id])
于 2020-02-26T14:38:05.563 回答