使用特定键更新 Postgres 中的 JSON 数组
Update JSON Array in Postgres with specific key
我有一个复杂的数组,在 table 列中如下所示:
{
"sometag": {},
"where": [
{
"id": "Krishna",
"nick": "KK",
"values": [
"0"
],
"function": "ADD",
"numValue": [
"0"
]
},
{
"id": "Krishna1",
"nick": "KK1",
"values": [
"0"
],
"function": "SUB",
"numValue": [
"0"
]
}
],
"anotherTag": [],
"TagTag": {
"tt": "tttttt",
"tt1": "tttttt"
}
在这个数组中,我想更新 id: "Krishna" 的函数和 numValue。
请帮忙。
这真的很讨厌,因为
- 更新 JSON 数组中的元素总是需要扩展数组
- 在上:数组是嵌套的
- 要更新的元素的标识符是兄弟而非父元素,这意味着,您必须按兄弟过滤
所以我想到了一个解决方案,但我想声明:您应该避免将此作为常规数据库操作!更好的是:
- 在后端解析你的JSON并在你的后端代码中进行操作
- 规范化数据库中的 JSON 如果这是一项常见任务,意思是:创建具有适当列的 table 并将 JSON 提取到 table结构体。不要将整个 JSON 个对象存储在数据库中!这将使每一项任务变得更加容易,并且性能更高!
SELECT
jsonb_set( -- 5
(SELECT mydata::jsonb FROM mytable),
'{where}',
updated_array
)::json
FROM (
SELECT
jsonb_agg( -- 4
CASE WHEN array_elem ->> 'id' = 'Krishna' THEN
jsonb_set( -- 3
jsonb_set(array_elem.value::jsonb, '{function}', '"ADDITION"'::jsonb), -- 2
'{numValue}',
'["0","1"]'::jsonb
)
ELSE array_elem::jsonb END
) as updated_array
FROM mytable,
json_array_elements(mydata -> 'where') array_elem -- 1
) s
- 将嵌套数组元素提取为每行一个元素
- 替换
function
值。请注意从类型 json
到类型 jsonb
的转换。这是必要的,因为没有 json_set()
函数,只有 jsonb_set()
。当然,如果您只有类型 jsonb
,则不需要强制转换。
- 替换
numValue
值
- 重新聚合数组
- 用新创建的数组对象替换原来JSON对象的
where
值。
我有一个复杂的数组,在 table 列中如下所示:
{
"sometag": {},
"where": [
{
"id": "Krishna",
"nick": "KK",
"values": [
"0"
],
"function": "ADD",
"numValue": [
"0"
]
},
{
"id": "Krishna1",
"nick": "KK1",
"values": [
"0"
],
"function": "SUB",
"numValue": [
"0"
]
}
],
"anotherTag": [],
"TagTag": {
"tt": "tttttt",
"tt1": "tttttt"
}
在这个数组中,我想更新 id: "Krishna" 的函数和 numValue。
请帮忙。
这真的很讨厌,因为
- 更新 JSON 数组中的元素总是需要扩展数组
- 在上:数组是嵌套的
- 要更新的元素的标识符是兄弟而非父元素,这意味着,您必须按兄弟过滤
所以我想到了一个解决方案,但我想声明:您应该避免将此作为常规数据库操作!更好的是:
- 在后端解析你的JSON并在你的后端代码中进行操作
- 规范化数据库中的 JSON 如果这是一项常见任务,意思是:创建具有适当列的 table 并将 JSON 提取到 table结构体。不要将整个 JSON 个对象存储在数据库中!这将使每一项任务变得更加容易,并且性能更高!
SELECT
jsonb_set( -- 5
(SELECT mydata::jsonb FROM mytable),
'{where}',
updated_array
)::json
FROM (
SELECT
jsonb_agg( -- 4
CASE WHEN array_elem ->> 'id' = 'Krishna' THEN
jsonb_set( -- 3
jsonb_set(array_elem.value::jsonb, '{function}', '"ADDITION"'::jsonb), -- 2
'{numValue}',
'["0","1"]'::jsonb
)
ELSE array_elem::jsonb END
) as updated_array
FROM mytable,
json_array_elements(mydata -> 'where') array_elem -- 1
) s
- 将嵌套数组元素提取为每行一个元素
- 替换
function
值。请注意从类型json
到类型jsonb
的转换。这是必要的,因为没有json_set()
函数,只有jsonb_set()
。当然,如果您只有类型jsonb
,则不需要强制转换。 - 替换
numValue
值 - 重新聚合数组
- 用新创建的数组对象替换原来JSON对象的
where
值。