在 Postgres 中搜索并更新 JSON 数组元素
Search and update a JSON array element in Postgres
我有一个 Jsonb 列,用于存储如下元素数组:
[
{"id": "11", "name": "John", "age":"25", ..........},
{"id": "22", "name": "Mike", "age":"35", ..........},
{"id": "33", "name": "Tom", "age":"45", ..........},
.....
]
我想用一个全新的对象替换第二个对象(id=22)。我不想一一更新每个 属性,因为有很多属性,它们的值都可能已经改变。我只想识别第二个元素并替换整个对象。
我知道有一个 jsonb_set()。但是,要更新第二个元素,我需要知道它的数组索引=1,所以我可以执行以下操作:
jsonb_set(data, '{1}', '{"id": "22", "name": "Don", "age":"55"}',true)
但我找不到任何方法来搜索和获取该索引。有人可以帮我吗?
我能想到的一种方法是结合 row_number
和 json_array_elements
:
-- test data
create table test (id integer, data jsonb);
insert into test values (1, '[{"id": "22", "name": "Don", "age":"55"}, {"id": "23", "name": "Don2", "age":"55"},{"id": "24", "name": "Don3", "age":"55"}]');
insert into test values (2, '[{"id": "32", "name": "Don", "age":"55"}, {"id": "33", "name": "Don2", "age":"55"},{"id": "34", "name": "Don3", "age":"55"}]');
select subrow, id, row_number() over (partition by id)
from (
select json_array_elements(data) as subrow, id
from test
) as t;
subrow | id | row_number
------------------------------------------+----+------------
{"id": "22", "name": "Don", "age":"55"} | 1 | 1
{"id": "23", "name": "Don2", "age":"55"} | 1 | 2
{"id": "24", "name": "Don3", "age":"55"} | 1 | 3
{"id": "32", "name": "Don", "age":"55"} | 2 | 1
{"id": "33", "name": "Don2", "age":"55"} | 2 | 2
{"id": "34", "name": "Don3", "age":"55"} | 2 | 3
-- apparently you can filter what you want from here
select subrow, id, row_number() over (partition by id)
from (
select json_array_elements(data) as subrow, id
from test
) as t
where subrow->>'id' = '23';
此外,请考虑您的架构设计。以这种方式存储数据可能不是最好的主意。
我有一个 Jsonb 列,用于存储如下元素数组:
[
{"id": "11", "name": "John", "age":"25", ..........},
{"id": "22", "name": "Mike", "age":"35", ..........},
{"id": "33", "name": "Tom", "age":"45", ..........},
.....
]
我想用一个全新的对象替换第二个对象(id=22)。我不想一一更新每个 属性,因为有很多属性,它们的值都可能已经改变。我只想识别第二个元素并替换整个对象。
我知道有一个 jsonb_set()。但是,要更新第二个元素,我需要知道它的数组索引=1,所以我可以执行以下操作:
jsonb_set(data, '{1}', '{"id": "22", "name": "Don", "age":"55"}',true)
但我找不到任何方法来搜索和获取该索引。有人可以帮我吗?
我能想到的一种方法是结合 row_number
和 json_array_elements
:
-- test data
create table test (id integer, data jsonb);
insert into test values (1, '[{"id": "22", "name": "Don", "age":"55"}, {"id": "23", "name": "Don2", "age":"55"},{"id": "24", "name": "Don3", "age":"55"}]');
insert into test values (2, '[{"id": "32", "name": "Don", "age":"55"}, {"id": "33", "name": "Don2", "age":"55"},{"id": "34", "name": "Don3", "age":"55"}]');
select subrow, id, row_number() over (partition by id)
from (
select json_array_elements(data) as subrow, id
from test
) as t;
subrow | id | row_number
------------------------------------------+----+------------
{"id": "22", "name": "Don", "age":"55"} | 1 | 1
{"id": "23", "name": "Don2", "age":"55"} | 1 | 2
{"id": "24", "name": "Don3", "age":"55"} | 1 | 3
{"id": "32", "name": "Don", "age":"55"} | 2 | 1
{"id": "33", "name": "Don2", "age":"55"} | 2 | 2
{"id": "34", "name": "Don3", "age":"55"} | 2 | 3
-- apparently you can filter what you want from here
select subrow, id, row_number() over (partition by id)
from (
select json_array_elements(data) as subrow, id
from test
) as t
where subrow->>'id' = '23';
此外,请考虑您的架构设计。以这种方式存储数据可能不是最好的主意。