如何更新 postgres 数组中的 json?
How to update json in postgres array?
我已附上 JSON 输入和输出
输入
{
"cap1": [
{
"fe1": [
{
"par1": 0,
"fet1": 6,
"fun1": [
{
"fnd1": [
{
"name": "v1",
"site": [
"w1",
"mb1",
"tb1"
]
}
]
}
]
}
],
"capab1": 2
},
{
"fe1": [
{
"par1": 0,
"fet1": 42,
"fun1": null
},
{
"par1": 42,
"fet1": 43,
"fun1": null
}
],
"capab1": 11
}
]
}
我想在 "capab1": 11
.
中添加 {"par1": 0, "fet1": 44, "fun1": null},{"par1": 0, "fet1": 45, "fun1": null}
输出应该是
{
"cap1": [
{
"fe1": [
{
"par1": 0,
"fet1": 6,
"fun1": [
{
"fnd1": [
{
"name": "v1",
"site": [
"w1",
"mb1",
"tb1"
]
}
]
}
]
}
],
"capab1": 2
},
{
"fe1": [
{
"par1": 0,
"fet1": 42,
"fun1": null
},
{
"par1": 42,
"fet1": 43,
"fun1": null
},
{
"par1": 0,
"fet1": 44,
"fun1": null
},
{
"par1": 0,
"fet1": 45,
"fun1": null
}
],
"capab1": 11
}
]
}
有点复杂。您可以使用 jsonb_array_elements
取消嵌套数组并获取要更新的路径。然后使用 JSONB_INSERT
更新 JSON,如下所示:
这是解决方案:
with cte as (
select *,
('{cap1,'||index1-1||',fe1,0}')::text[] as json_path
from test,
jsonb_array_elements(col->'cap1') with ordinality arr1 (vals1,index1)
where (vals1->>'capab1')::int=11
)
update test
set col = jsonb_insert(test.col,cte.json_path,'[{"par1": 0, "fet1": 44, "fun1": null},{"par1": 0, "fet1": 45, "fun1": null}]'::jsonb,true)
from cte
where test.id=cte.id
我已附上 JSON 输入和输出
输入
{
"cap1": [
{
"fe1": [
{
"par1": 0,
"fet1": 6,
"fun1": [
{
"fnd1": [
{
"name": "v1",
"site": [
"w1",
"mb1",
"tb1"
]
}
]
}
]
}
],
"capab1": 2
},
{
"fe1": [
{
"par1": 0,
"fet1": 42,
"fun1": null
},
{
"par1": 42,
"fet1": 43,
"fun1": null
}
],
"capab1": 11
}
]
}
我想在 "capab1": 11
.
{"par1": 0, "fet1": 44, "fun1": null},{"par1": 0, "fet1": 45, "fun1": null}
输出应该是
{
"cap1": [
{
"fe1": [
{
"par1": 0,
"fet1": 6,
"fun1": [
{
"fnd1": [
{
"name": "v1",
"site": [
"w1",
"mb1",
"tb1"
]
}
]
}
]
}
],
"capab1": 2
},
{
"fe1": [
{
"par1": 0,
"fet1": 42,
"fun1": null
},
{
"par1": 42,
"fet1": 43,
"fun1": null
},
{
"par1": 0,
"fet1": 44,
"fun1": null
},
{
"par1": 0,
"fet1": 45,
"fun1": null
}
],
"capab1": 11
}
]
}
有点复杂。您可以使用 jsonb_array_elements
取消嵌套数组并获取要更新的路径。然后使用 JSONB_INSERT
更新 JSON,如下所示:
这是解决方案:
with cte as (
select *,
('{cap1,'||index1-1||',fe1,0}')::text[] as json_path
from test,
jsonb_array_elements(col->'cap1') with ordinality arr1 (vals1,index1)
where (vals1->>'capab1')::int=11
)
update test
set col = jsonb_insert(test.col,cte.json_path,'[{"par1": 0, "fet1": 44, "fun1": null},{"par1": 0, "fet1": 45, "fun1": null}]'::jsonb,true)
from cte
where test.id=cte.id