如何直接通过某个键的值更新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)