json - 如何使用 jq 获取 json 流的嵌套键

标签 json schema jq

我正在尝试设计一些关系表来保存各种 json 流的解析输出。数据流具有相当复杂的结构,为了便于表设计,我需要知道每个流的每一级嵌套键。我不知道如何使用 jq 从流中获取每个嵌套的键。下面是一个简化的代表性json流。

{
  "startAt": 0,
  "total": 5315,
  "issues": [
    {
      "id": "44269",
      "name": "someName",
      "fields": {
        "fixVersions": [
          {
            "id": "11401",
            "releaseDate": "2016-09-30"
          }
        ],
        "status": {
          "id": "10110",
          "statusCategory": {
            "id": 3,
            "name": "Done"
          }
        }
      }
    },
    {
      "id": "44270",
      "key": "LEAD-XXXX",
      "fields": {
        "assignee": {
          "id": "10111",
          "name": "Don"
        },
        "status": {
          "id": "10110",
          "statusCategory": {
            "id": 2,
            "name": "inProgress"
          }
        }
      }
    }
  ]
}

我期待以下输出。我很乐意有更好的方法来帮助我进行 table 设计。
startAt
total
issues: []
issues:id
issues:name
issues:key
issues:fields
issues:fields:fixVersions: []
issues:fields:fixVersions:id
issues:fields:fixVersions:releaseDate
issues:fields:status
issues:fields:status:id
issues:fields:status:statusCategory
issues:fields:status:statusCategory:id
issues:fields:status:statusCategory:name
issues:fields:assignee
issues:fields:assignee:id
issues:fields:assignee:name

如何使用 jq 获取上述流的嵌套键。非常感谢帮助。

最佳答案

I would be more than happy to have a better approach ...



如果我是你,我会从以下几点开始(也许结束):
[paths(scalars) | map(if type == "number" then 0 else . end)]
| unique
| .[]

在您的示例中,使用 -cr 命令行选项会产生:
["issues",0,"fields","assignee","id"]
["issues",0,"fields","assignee","name"]
["issues",0,"fields","fixVersions",0,"id"]
["issues",0,"fields","fixVersions",0,"releaseDate"]
["issues",0,"fields","status","id"]
["issues",0,"fields","status","statusCategory","id"]
["issues",0,"fields","status","statusCategory","name"]
["issues",0,"id"]
["issues",0,"key"]
["issues",0,"name"]
["startAt"]
["total"]

您可以更接近您所表示的您希望我将数字 0 映射到字符串的内容,但是您必须小心该字符串和键名之间的潜在冲突。为了显示:
[paths(scalars) | map(if type == "number" then "[]" else . end)]
| unique
| .[]
| join(":")

产生:
issues:[]:fields:assignee:id
issues:[]:fields:assignee:name
issues:[]:fields:fixVersions:[]:id
issues:[]:fields:fixVersions:[]:releaseDate
issues:[]:fields:status:id
issues:[]:fields:status:statusCategory:id
issues:[]:fields:status:statusCategory:name
issues:[]:id
issues:[]:key
issues:[]:name
startAt
total

请注意,这种方法产生的结果与基于模式推理的方法基本相同。这是一件好事。

使用 INDEX/2

使用 unique/0如上所述有两个潜在的缺点:(1)输出的排序不反射(reflect)数据中的排序; (2) 效率(尽管在实践中这不太可能是一个真正的问题,除了具有大量叶路径的 JSON 文本)。

无论如何,INDEX/2可以用来代替 unique .如果您的 jq 没有 INDEX/2 ,这里给出了它的定义。

简而言之:
def INDEX(stream; idx_expr):
  reduce stream as $row ({};
    .[$row|idx_expr|
      if type != "string" then tojson
      else .
      end] |= $row);

INDEX(paths(scalars)
      | map(if type == "number" then "[]" else . end); .)
| .[]
| join(":")

产量:
startAt
total
issues:[]:id
issues:[]:name
issues:[]:fields:fixVersions:[]:id
issues:[]:fields:fixVersions:[]:releaseDate
issues:[]:fields:status:id
issues:[]:fields:status:statusCategory:id
issues:[]:fields:status:statusCategory:name
issues:[]:key
issues:[]:fields:assignee:id
issues:[]:fields:assignee:name

空数组的路径

如果您还希望报告空数组的路径,您可以(例如)简单地将“路径(标量)”更改为“(路径(标量),路径(数组))”。

关于json - 如何使用 jq 获取 json 流的嵌套键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46973467/

相关文章:

ios - AFNetworking v3.1.0 multipartFormRequestWithMethod 上传带引号的 JSON 数值

javascript - 来自 Facebook FQL 函数的 JSON JS 对象数组

hibernate - 在内存数据库(HSQLDB或H2)上使用多个架构域运行grails

database-design - 使用缩写表名为表中的每个字段名添加前缀是一个好习惯吗?

json - 如何使用 jq 更新 json 文件中的子项?

android - 分页 - 你关注的推特人

javascript - ajax 响应在 jquery 解析器之前反序列化

XML 架构 : how to have multiple identical elements?

json - 使用 jq 获取数组中 shell 定义的 JSON 对象内特定键的值

json - 使用 jq + bash 将 json 转换为 ini 文件