使用 PostgreSQL 查询更新一个复杂的 JSONB 对象以删除一个 sub-sub-属性
Update a complex JSONB object to remove a sub-sub-property with a PostgreSQL query
假设我在列 my_jsonb
PostgreSQL 数据库 table 中有这样的 JSONB 数据,具有以下模式:
[
{
"foo": {
"bar": [
{
"baz": 1,
"qux": 2
}
]
}
},
{
"foo": {
"bar": [
{
"baz": 3,
"qux": 4
},
{
"baz": 5,
"qux": 6
}
]
}
}
]
换句话说,每一列 my_jsonb
都有一个 foo
的列表,其中有一个 属性 bar
包含具有两个属性的对象数组 baz
和 qux
.
我现在认为 baz
属性 已经过时了,我想删除它以得到这个:
[
{
"foo": {
"bar": [
{
"qux": 2
}
]
}
},
{
"foo": {
"bar": [
{
"qux": 4
},
{
"qux": 6
}
]
}
}
]
我可以使用脚本在每个 bar
项目中一个接一个地删除这些 baz
属性,但它会非常长。有没有一种方法可以更新复杂的 JSONB 对象以删除 sub-sub-属性 而无需使用脚本执行某些操作?
一行一行的做就可以了(我的实际只有100k行table,所以我认为每一行都迭代是安全的,我唯一想要的是一次删除一行中的所有 baz
个属性).
有可能吗?
在 json 结构僵硬的情况下,您可以通过以下方式重新创建 json 对象:
select id, jsonb_agg(new_foos order by fo)
from (
select
id, fo,
jsonb_build_object(
'foo',
jsonb_build_object(
'bar',
jsonb_agg(bars- 'baz' order by bo))
) as new_foos
from my_table
cross join
jsonb_array_elements(json_data)
with ordinality as foos(foos, fo)
cross join
jsonb_array_elements(foos->'foo'->'bar')
with ordinality as bars(bars, bo)
group by id, fo
) s
group by id
请注意,我们将聚合与 with ordinality
获得的顺序功能结合使用,以保留数组元素的原始顺序。
假设我在列 my_jsonb
PostgreSQL 数据库 table 中有这样的 JSONB 数据,具有以下模式:
[
{
"foo": {
"bar": [
{
"baz": 1,
"qux": 2
}
]
}
},
{
"foo": {
"bar": [
{
"baz": 3,
"qux": 4
},
{
"baz": 5,
"qux": 6
}
]
}
}
]
换句话说,每一列 my_jsonb
都有一个 foo
的列表,其中有一个 属性 bar
包含具有两个属性的对象数组 baz
和 qux
.
我现在认为 baz
属性 已经过时了,我想删除它以得到这个:
[
{
"foo": {
"bar": [
{
"qux": 2
}
]
}
},
{
"foo": {
"bar": [
{
"qux": 4
},
{
"qux": 6
}
]
}
}
]
我可以使用脚本在每个 bar
项目中一个接一个地删除这些 baz
属性,但它会非常长。有没有一种方法可以更新复杂的 JSONB 对象以删除 sub-sub-属性 而无需使用脚本执行某些操作?
一行一行的做就可以了(我的实际只有100k行table,所以我认为每一行都迭代是安全的,我唯一想要的是一次删除一行中的所有 baz
个属性).
有可能吗?
在 json 结构僵硬的情况下,您可以通过以下方式重新创建 json 对象:
select id, jsonb_agg(new_foos order by fo)
from (
select
id, fo,
jsonb_build_object(
'foo',
jsonb_build_object(
'bar',
jsonb_agg(bars- 'baz' order by bo))
) as new_foos
from my_table
cross join
jsonb_array_elements(json_data)
with ordinality as foos(foos, fo)
cross join
jsonb_array_elements(foos->'foo'->'bar')
with ordinality as bars(bars, bo)
group by id, fo
) s
group by id
请注意,我们将聚合与 with ordinality
获得的顺序功能结合使用,以保留数组元素的原始顺序。