如何基于属性名更新JSONB数组?

如何基于属性名更新JSONB数组?,json,postgresql,Json,Postgresql,我想基于objectId使用JSONB数据类型更新存储在列中的以下JSON数组的字段 [ { objectId: 'gDKn1jM5d', objectType: 'type1', posX: 50, posY: 100, }, { objectId:

我想基于objectId使用JSONB数据类型更新存储在列中的以下JSON数组的字段

        [
            {
                objectId: 'gDKn1jM5d',
                objectType: 'type1',
                posX: 50,
                posY: 100,
            },
            {
                objectId: '4dg5E8BDv',
                objectType: 'type2',
                posX: 50,
                posY: 100,
            },
            {
                objectId: 'ZmCwOf5N2',
                objectType: 'type3',
                posX: 100,
                posY: 150,
            }
        ]
在Mongodb中,我可以使用一个简单的update语句,但在postgres中找不到一种方法

例如,我想将objectId为'ZmCwOf5N2'的所有数组元素更新为posX值300,这意味着它只会影响第三个数组项

我正在寻找一个简单的SQL语句来执行更新。 博士后的版本是11

我不可能安装扩展,因为我将数据库用作服务提供商。然而,如果没有简单的方法来完成update语句,我将能够使用例如C代码添加一个postgres函数

UPDATE tbl t
SET    js = 
   (
   SELECT jsonb_agg(CASE WHEN elem->>'objectId' = 'ZmCwOf5N2'
                         THEN jsonb_set(elem, '{posX}', to_jsonb(int '300'))
                         ELSE elem
                    END) AS  js1 
   FROM   jsonb_array_elements(t.js) elem
   )
WHERE  t.js @> '[{"objectId": "ZmCwOf5N2"}]';
请注意,此

如果缺少“posX”键,则添加该键 即使在没有任何更改的情况下也会更新行 要仅更新现有键并仅在更新实际更改值时更新行,请执行以下操作:

UPDATE tbl t
SET    js = 
   (
   SELECT jsonb_agg(CASE WHEN elem->>'objectId' = 'ZmCwOf5N2'
                         THEN jsonb_set(elem, '{posX}', to_jsonb(int '300'), false)  -- !
                         ELSE elem
                    END) AS  js1 
   FROM   jsonb_array_elements(t.js) elem
   )
WHERE  t.js @> '[{"objectId": "ZmCwOf5N2"}]'
AND    js <>
   (
   SELECT jsonb_agg(CASE WHEN elem->>'objectId' = 'ZmCwOf5N2'
                         THEN jsonb_set(elem, '{posX}', to_jsonb(int '300'), false)
                         ELSE elem
                    END) AS  js1 
   FROM   jsonb_array_elements(t.js) elem
   );  --!
见:


清晰的答案是@I have seen,但它没有描述如何通过属性值更新数组项,而只是通过数组索引。你可以检查我对这个问题的回答:我也看到了。你知道这是唯一的解决办法吗?如果是这样,我想这意味着基于属性数组的条件操作还不受支持。这看起来是一个非常好的解决方案。谢谢!你知道是否计划了一个本机解决方案,一个专门针对该用例的解决方案,以便用更少的代码完成它吗?@microman:这是目前Postgres 11最短、最快的方法。还要注意我添加的变体!计划为Postgres 12添加部分SQL/JSON路径语言。不确定这是否包括在内。