如何基于属性名更新JSONB数组?
我想基于objectId使用JSONB数据类型更新存储在列中的以下JSON数组的字段如何基于属性名更新JSONB数组?,json,postgresql,Json,Postgresql,我想基于objectId使用JSONB数据类型更新存储在列中的以下JSON数组的字段 [ { objectId: 'gDKn1jM5d', objectType: 'type1', posX: 50, posY: 100, }, { objectId:
[
{
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路径语言。不确定这是否包括在内。