规范化 jq 中的数据

Normalizing data in jq

想象一下看起来像这样的数据:

[{
    "names": {
        "official_full": "John Smith",
        "nickname": "Johnny"
    },
    "positions": [{
        "start": "1993-01-05",
        "end": "2002-12-03",
        "title": "Executive VP of Operations",
        "city": "Winnipeg",
        "state": "Michigan"
    }, ...]
}, ...]

在 jq 中是否可以像下面这样规范化数据?

{
    people: [{
        "full_name": "John Smith"
    }, ...],

    terms: [{
        "start": "1993-01-05",
        "end": "2002-12-03",
        "person": 1,
        "job": 0
    }, ...],

    jobs: [{
        "title": "Executive VP of Operations",
        "location": 0
    }, ...],

    locations: [{
        "city": "Winnipeg",
        "state": "Michigan"
    }, ...]
}

我是 jq 的新手,所以我不知道从哪里开始。我的主要问题是如何预先创建一个对象,然后在我遍历传入的 json 即

时填充该对象
{
    people: [],
    terms: [],
    jobs: [],
    locations: []
}

以及如何获取附加对象的索引?

我不确定使用 jq 是否容易做到这一点。我可能只是使用 normalizrjs 编写一个 nodejs 脚本。

另一个问题是确保 joblocation 之类的对象不重复,因此我想确保不存在具有重复字段的对象。这个我觉得可能没那么难。我只需要在插入对象之前将对象与数组中的内容进行比较

如果我正确理解你的问题,你应该能够使用 reduce 完成你想要的,按照以下行:

reduce .[] as $o
  ({
     people: [],
     terms: [],
     jobs: [],
     locations: []
   }; ......
 )

请参阅有关 reduce 的 jq 文档,但简而言之,您可以将 ...... 替换为 jq 说明以构建您的规范化表示。

检查重复项的最简单方法可能是使用 index/1。我建议使用辅助函数 (def ...) 使内容易于阅读和维护。

数字 id

如果你需要生成一个数字id,那么使用成语可能更容易:

. as $in | reduce range(0;length) as $i (INITIAL; $in[$i] as $o | ......)