json - 使用 jq 提取 JSON 数据结构中的公共(public)前缀

标签 json jq

我有一个 JSON 数据集,其中包含从 Redis 存储中提取的大约 870 万个键值对,其中每个键保证是一个 8 位数字,并且该键是一个 8 个字母数字字符值,即

[{
"91201544":"INXX0019",
"90429396":"THXX0020",
"20140367":"ITXX0043",
 ...
}]

为了减少 Redis 内存使用,我想将其转换为哈希的哈希,其中哈希前缀键是键的前 6 个字符(参见 this link),然后将其存储回 Redis。

具体来说,我希望生成的 JSON 数据结构(然后我将编写一些代码来解析此 JSON 结构并创建一个由 HSET 等组成的 Redis 命令文件)看起来更像

[{
 "000000": { "00000023": "INCD1234",
             "00000027": "INCF1423",
              ....
           },
 ....
 "904293": { "90429300": "THXX0020",
             "90429302": "THXX0024",
             "90429305": "THXY0013"}
 }]

因为jq给我留下了深刻的印象并且我正在尝试更加精通函数式编程,我想使用 jq 来完成这项任务。到目前为止,我已经想出了以下内容:

% jq '.[0] | to_entries | map({key: .key, pfx: .key[0:6], value: .value}) | group_by(.pfx)'

这给了我类似的东西

[
  [
    {
      "key": "00000130",
      "pfx": "000001",
      "value": "CAXX3231"
    },
    {
      "key": "00000162",
      "pfx": "000001",
      "value": "CAXX4606"
    }
  ],
  [
    {
      "key": "00000238",
      "pfx": "000002",
      "value": "CAXX1967"
    },
    {
      "key": "00000256",
      "pfx": "000002",
      "value": "CAXX0727"
    }
  ],
  ....
]

我试过以下方法:

% jq 'map(map({key: .pfx, value: {key, value}})) 
      | map(reduce .[] as $item ({}; {key: $item.key, value: [.value[], $item.value]} )) 
      | map( {key, value: .value | from_entries} ) 
      | from_entries'

这确实给了我正确的结果,但也为

的每个减少(我相信)打印出一个错误
jq: error: Cannot iterate over null

最终结果是

{
   "000001": {
     "00000130": "CAXX3231",
     "00000162": "CAXX4606"
   },
   "000002": {
     "00000238": "CAXX1967",
     "00000256": "CAXX0727"
   },
   ...
}

这是正确的,但我怎样才能避免同时抛出此 stderr 警告?

最佳答案

我不确定此处是否有足够的数据来评估问题的根源。我发现很难相信你尝试的结果。我一直遇到错误。

试试这个过滤器:

.[0]
    | to_entries
    | group_by(.key[0:6])
    | map({
          key:   .[0].key[0:6],
          value: map(.key=.key[6:8]) | from_entries
      })
    | from_entries

给定如下所示的数据:

[{
    "91201544":"INXX0019",
    "90429396":"THXX0020",
    "20140367":"ITXX0043",
    "00000023":"INCD1234",
    "00000027":"INCF1423",
    "90429300":"THXX0020",
    "90429302":"THXX0024",
    "90429305":"THXY0013"
}]

结果:

{
  "000000": {
    "23": "INCD1234",
    "27": "INCF1423"
  },
  "201403": {
    "67": "ITXX0043"
  },
  "904293": {
    "00": "THXX0020",
    "02": "THXX0024",
    "05": "THXY0013",
    "96": "THXX0020"
  },
  "912015": {
    "44": "INXX0019"
  }
}

关于json - 使用 jq 提取 JSON 数据结构中的公共(public)前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24817244/

相关文章:

JSON:@Transient 字段未序列化

javascript - 将数组对象转换为字符串值

JavaScript 属性错误处理

映射到 JPA Temporal.Type TIMESTAMP 的 mysql 日期时间。仅获取日期,JSON 响应中没有时间

json - 使用 jq 对 JSON 中特定字段的值求平均值

key - jq 中包含 '@' 和 '-' 的转义字段名称?

json - 根据对象键/值在对象内连接 2 个数组

c# - JsonSchemaGenerator 未将字段设置为 required = false

linux - 将 "jq"输出管道到 "less"时如何保持颜色?

indexing - 如何使用 jq 将数组中对象的数组索引注入(inject)到对象中