如何直接通过某个键的值更新pg的json数组数据?
How to update pg's json array data by some key's value directly?
有些事情看起来很简单,但使用起来却很困难。在我的pg函数中,我经常使用json数据来存储数组数据。
看看下面我的 json 数据:
[
{
"id":5,
"name":"John",
"sex":"male"
},
{
"id":4,
"name":"Alice",
"sex":"female"
},
{
"id":6,
"name":"Jack",
"sex":"male"
}
]
比如我想修改数组子对象的某个值,即我只想修改"name"为"Tom",其中"id"为5, 如何直接解决?
如果我使用jsonb_set函数,你知道jsonb_set函数不支持条件,我应该首先知道数组子对象的索引,就像
jsonb_set(myjsonb,'{0,name}','Tome')
但是我首先不知道索引,我只知道元素对象的某个键的值。
当然,我可以先把subobject放到一个table里,看起来很复杂,就像下面这样:
select
fserial-1 into myindex
from jsonb_array_elements(myjson) with ordinality vids(frow ,fserial)
where cast(frow->>'id' as bigint)=5;
我想也许我可以用jsonb_set和json路径一起直接解决,但是我查看了pg's documention,我找不到正确的方法。
PG为json数组提供了那么多路径运算符和方法,包括.size()等等,为什么不提供.index()方法呢?为什么 jsonb_set 函数支持条件?
你能给我一些直接解决这个问题的简单方法吗?
您可以取消嵌套、修改和重新聚合:
select json_agg(
case when obj ->> 'id' = '5'
then obj - 'name' || '{"name": "Tom"}'::jsonb
else obj
end
order by rn
) as newjson
from jsonb_array_elements(myjson) with ordinality x(obj, rn)
有些事情看起来很简单,但使用起来却很困难。在我的pg函数中,我经常使用json数据来存储数组数据。
看看下面我的 json 数据:
[
{
"id":5,
"name":"John",
"sex":"male"
},
{
"id":4,
"name":"Alice",
"sex":"female"
},
{
"id":6,
"name":"Jack",
"sex":"male"
}
]
比如我想修改数组子对象的某个值,即我只想修改"name"为"Tom",其中"id"为5, 如何直接解决?
如果我使用jsonb_set函数,你知道jsonb_set函数不支持条件,我应该首先知道数组子对象的索引,就像
jsonb_set(myjsonb,'{0,name}','Tome')
但是我首先不知道索引,我只知道元素对象的某个键的值。
当然,我可以先把subobject放到一个table里,看起来很复杂,就像下面这样:
select
fserial-1 into myindex
from jsonb_array_elements(myjson) with ordinality vids(frow ,fserial)
where cast(frow->>'id' as bigint)=5;
我想也许我可以用jsonb_set和json路径一起直接解决,但是我查看了pg's documention,我找不到正确的方法。
PG为json数组提供了那么多路径运算符和方法,包括.size()等等,为什么不提供.index()方法呢?为什么 jsonb_set 函数支持条件?
你能给我一些直接解决这个问题的简单方法吗?
您可以取消嵌套、修改和重新聚合:
select json_agg(
case when obj ->> 'id' = '5'
then obj - 'name' || '{"name": "Tom"}'::jsonb
else obj
end
order by rn
) as newjson
from jsonb_array_elements(myjson) with ordinality x(obj, rn)