PostgreSQL 如何删除 JSONB 中的嵌套键?
数据小许
结论
jsonb_delete(data, '{address, state}') 的第二个参数是 text 值,表示要删除的单个顶层键,并非 JSONB 路径。因此,它不会进入 address 对象删除 state。要删除嵌套字段,应使用路径删除操作符 #-:
UPDATE my_table
SET data = data #- '{address,state}'
WHERE id = 1
RETURNING *;
执行后,data 中的 address 会变成 {"city": "New York"}。
原因
原语句中的 '{address, state}' 是一个字符串参数。jsonb_delete 按单键删除语义处理这个值,会将整个字符串作为顶层键名查找,不会自动把逗号分隔的文本解析为路径。示例 JSON 的顶层没有名为 address, state 的键,因此值保持不变。
UPDATE 1 表示有一行符合 WHERE id = 1 并由更新语句处理,但这不代表 JSONB 内容中的目标字段一定已删除。
按路径删除嵌套字段
PostgreSQL 的 #- 操作符接受 text[] 路径,可删除该路径指向的字段或数组元素。这里的路径依次包含 address 和 state:
UPDATE my_table
SET data = data #- '{address,state}'
WHERE id = 1
RETURNING *;
预期返回的 data 内容为:
{
"age": 30,
"name": "John",
"address": {
"city": "New York"
}
}
官方文档说明,jsonb #- text[] 用于删除指定路径上的字段或数组元素;jsonb - text 删除对象键时只作用于当前层级。PostgreSQL 18 JSON Functions and Operators
注意事项
路径中的每一项对应一层对象键或数组索引。如果目标路径不存在,JSONB 值通常会原样返回,不会因此报错。只需删除顶层键时,可以使用 data - 'address';删除嵌套路径时则使用 #-。
备注:内容仅供参考。
