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

如何用jsonb_path_query()获取带根键的过滤后JSONB数据?

在PostgreSQL 13中过滤JSONB并保留根键的方法

你当前的查询能正确过滤出符合条件的子对象,但无法保留对应的根键;而尝试的路径表达式因判断逻辑错误,返回了整个原始JSON对象。以下是两种可行的解决方法:

方法1:使用jsonb_each展开后过滤再聚合

这种方法通过将顶层JSON对象拆分为键值对,过滤出符合条件的项后重新组合成JSON对象:

SELECT jsonb_object_agg(key, value)
FROM jsonb_each('{
  "100": {
    "name": "test",
    "priority": 5
  },
  "101": {
    "name": "test2",
    "priority": 10
  },
  "102": {
    "name": "test3",
    "priority": 15
  }                     
}'::jsonb)
WHERE (value->>'priority')::integer > 10;

执行后会返回期望的结果:

{
    "102": {
        "name": "test3",
        "priority": 15
    }
}

方法2:使用JSON路径的keyvalue()函数

如果你更倾向于用JSON路径表达式实现,可以借助keyvalue()函数将顶层对象转换为键值对数组,过滤后再聚合:

SELECT jsonb_object_agg(item.key, item.value)
FROM jsonb_path_query(
  '{
    "100": {
      "name": "test",
      "priority": 5
    },
    "101": {
      "name": "test2",
      "priority": 10
    },
    "102": {
      "name": "test3",
      "priority": 15
    }                     
  }'::jsonb,
  '$.keyvalue() ? (@.value.priority > 10)'
) AS item;

keyvalue()会把每个顶层键值对转换为{"key": "键名", "value": 子对象}的结构,路径表达式$.keyvalue() ? (@.value.priority > 10)会筛选出子对象priority大于10的项,最后用jsonb_object_agg重新组合成目标JSON。

为什么你的尝试查询失败?

你之前的路径表达式$ ? (@.*.priority > 10)的逻辑是判断整个JSON对象是否存在任意子对象满足priority>10,只要有一个符合条件,就会返回整个原始对象,而非过滤掉不符合条件的子键值对,这就是返回全部数据的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:54:28