You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用jq展开含对象与数组的复杂JSON对象的技术咨询

嵌套JSON展平的jq解决方案

问题背景

我们从客户处接收了一份高度嵌套的JSON数据(客户通过嵌套减少重复数据、降低传输量),示例包含多层可选嵌套对象与数组。需要将其展平为无笛卡尔积的CSV或单行JSON文档,但使用jq处理时遇到以下问题:

  • 非对象数组(如字符串数组)会产生笛卡尔积(数组每个元素生成单独行)
  • 数组为null时,对应行丢失或字段无输出
    尝试多段jq代码后,仍存在aon为null的行丢失、无法正常访问aos数组等问题。

1. 针对示例JSON的jq过滤器

假设示例JSON结构如下(包含null数组、字符串数组、嵌套对象):

[
  {
    "id": "001",
    "name": "Item1",
    "aon": null,
    "aos": ["X", "Y"],
    "details": {
      "type": "A",
      "tags": ["tag1", "tag2"]
    }
  },
  {
    "id": "002",
    "name": "Item2",
    "aon": [{"val": "a"}, {"val": "b"}],
    "aos": null,
    "details": {
      "type": "B",
      "tags": null
    }
  }
]

对应的jq过滤器(实现无笛卡尔积展平,保留所有行,处理null和非对象数组):

# 统一处理null、数组、值类型的函数
def normalize:
  if . == null then null
  elif type == "array" then
    # 值类型数组转逗号分隔字符串,对象数组提取值后拼接
    if all(.[]; type == "object") then map(.val) | join(", ") else join(", ") end
  else .
  end;

# 遍历每个顶层对象,展平字段
.[] | {
  id: .id,
  name: .name,
  aon: normalize(.aon),
  aos: normalize(.aos),
  details_type: .details.type,
  details_tags: normalize(.details.tags)
}

执行后输出(每个顶层对象对应一行,无笛卡尔积,null字段保留):

{"id":"001","name":"Item1","aon":null,"aos":"X, Y","details_type":"A","details_tags":"tag1, tag2"}
{"id":"002","name":"Item2","aon":"a, b","aos":null,"details_type":"B","details_tags":null}

2. jq中通用处理嵌套对象、数组及值类型数组的方法

核心思路

  • 统一处理null:明确对null值返回null,避免过滤掉包含null字段的行
  • 区分数组类型:值类型数组(字符串/数字)转成逗号分隔字符串;对象数组按需选择递归展平或保留结构
  • 避免笛卡尔积:仅遍历顶层对象,对每个对象内的嵌套字段单独处理,不进行多数组交叉循环

通用处理函数示例

# 递归展平嵌套对象,处理所有类型的数组和null
def flatten_obj(prefix):
  if . == null then null
  elif type == "array" then
    if length == 0 then null
    elif all(.[]; type == "object") then
      map(flatten_obj("")) | join("; ")
    else join(", ")
    end
  elif type == "object" then
    to_entries | reduce .[] as $entry ({};
      . + flatten_obj("\(prefix)\($entry.key)_")($entry.value)
    )
  else {("\(prefix[:-1])"): .}
  end;

# 使用示例:展平任意嵌套JSON的所有字段
.[] | flatten_obj("")

关键技巧

  • 使用paths(scalars)自动遍历所有标量字段,实现完全自动化展平:
.[] | reduce paths(scalars) as $path ({};
  . + {
    ($path | join("_")): getpath($path) | if type == "array" then join(", ") else . end
  }
)
  • 用//运算符处理null fallback,比如(.aon // [])确保数组不为null,但如需保留null直接用.aon即可

内容的提问来源于stack exchange,提问作者bunkfish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 08:05:29