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

Slonik:如何安全使用JSONB_PATH_MATCH查询JSONB对象?

问题:Slonik中安全查询JSONB路径匹配的简便实现

我的PostgreSQL表中有一个存储聚合JSONB对象的列,数据示例如下:

id  | agg_jsonb_objects
------+---------------------------------------------------------
   1  | {"recordA": {"fieldA": "A"}, "recordB": {"fieldA": "B"}}

需求是查询所有包含值为“B”的“fieldA”的行,在终端中用以下SQL可以实现:

SELECT id
FROM your_table
WHERE JSONB_PATH_MATCH(agg_jsonb_objects, 'exists($ ?(@.**.fieldA == "B"))')

但用Slonik构建服务端安全查询时遇到问题:

  • 使用raw()可以运行,但存在SQL注入风险;
  • 直接传入参数会报错“could not determine data type of parameter $1”;
  • 手动处理不同类型值的格式(如字符串加引号、数值不用加)可以运行,但过于繁琐,想找更简便的实现方式。
解决方案

方法1:参数化JSON路径查询(适配复杂路径)

利用PostgreSQL的jsonb_build_object将参数封装为JSONB对象,在路径表达式中通过命名参数引用,Slonik可安全传递参数且无需手动处理格式:

const targetValue = 'B';

const query = sql`
  SELECT id
  FROM your_table
  WHERE jsonb_path_match(
    agg_jsonb_objects,
    'exists($ ?(@.**.fieldA == $val))',
    jsonb_build_object('val', ${targetValue})
  )
`;

原理:jsonb_build_object会根据传入参数的类型自动生成对应JSON类型的值,路径表达式中的$val会引用这个JSONB对象中的键值,PostgreSQL能自动识别参数类型,避免手动拼接引号或处理类型差异。

方法2:展开JSONB后过滤(直观易维护)

如果JSONB结构是顶层键值对的聚合,可通过jsonb_each展开对象后直接过滤,Slonik参数处理更简单:

const targetValue = 'B';

const query = sql`
  SELECT DISTINCT t.id
  FROM your_table t
  JOIN jsonb_each(t.agg_jsonb_objects) j(key, value)
  ON j.value->>'fieldA' = ${targetValue}
`;

原理:jsonb_each将顶层JSONB对象拆分为键值行,通过->>提取fieldA的文本值后直接和参数比较,完全规避JSON路径表达式的参数类型问题,代码可读性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 17:01:03