Postgresql 在Postgres中搜索并更新JSON数组元素

Postgresql 在Postgres中搜索并更新JSON数组元素,postgresql,postgresql-9.5,Postgresql,Postgresql 9.5,我有一个Jsonb列,用于存储元素数组,如下所示: [ {"id": "11", "name": "John", "age":"25", ..........}, {"id": "22", "name": "Mike", "age":"35", ..........}, {"id": "33", "name": "Tom", "age":"45", ..........}, ..... ] jsonb_set(data, '{1}', '{"id": "22", "nam

我有一个Jsonb列,用于存储元素数组,如下所示:

[ 
  {"id": "11", "name": "John", "age":"25", ..........}, 
  {"id": "22", "name": "Mike", "age":"35", ..........},
  {"id": "33", "name": "Tom",  "age":"45", ..........},
  .....
]
jsonb_set(data, '{1}', '{"id": "22", "name": "Don", "age":"55"}',true) 
我想用一个全新的对象替换第二个对象(id=22)。我不想一个接一个地更新每个属性,因为有很多属性,它们的值都可能已经更改。我只想识别第二个元素并替换整个对象

我知道有一个jsonb_集合()。但是,要更新第二个元素,我需要知道它的数组索引=1,以便执行以下操作:

[ 
  {"id": "11", "name": "John", "age":"25", ..........}, 
  {"id": "22", "name": "Mike", "age":"35", ..........},
  {"id": "33", "name": "Tom",  "age":"45", ..........},
  .....
]
jsonb_set(data, '{1}', '{"id": "22", "name": "Don", "age":"55"}',true) 

但是我找不到任何方法来搜索和获取索引。有人能帮我吗

我能想到的一种方法是将
行数
json\u数组元素

-- 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';

此外,请考虑您的模式设计。以这种方式存储数据可能不是最好的方法

我能想到的一种方法是将
行数
json\u数组元素

-- 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';

此外,请考虑您的模式设计。以这种方式存储数据可能不是最好的方法

问:你试过JSON操作符了吗?问:你试过JSON操作符了吗?谢谢你的快速回复@blurcat。我试图用一个查询来完成更新。在您的解决方案中,如何将行号传递给jsonb_集()?我字面上回答了您的问题“获取该索引”。。如果可能的话,在一个查询中完成这项工作会很尴尬。此外,考虑有多个子行匹配ID的情况。如果您有自由改变模式,我认为最好把这些子行放在一个单独的表中。好,@ FrimrCAT。非常感谢。你能详细阐述一下你对模式设计的建议吗?有什么更好的方法吗?@user3487866将数组项放在一个单独的表中如何?感谢您的快速响应@blurcat。我试图用一个查询来完成更新。在您的解决方案中,如何将行号传递给jsonb_集()?我字面上回答了您的问题“获取该索引”。。如果可能的话,在一个查询中完成这项工作会很尴尬。此外,考虑有多个子行匹配ID的情况。如果您有自由改变模式,我认为最好把这些子行放在一个单独的表中。好,@ FrimrCAT。非常感谢。你能详细阐述一下你对模式设计的建议吗?有什么更好的方法?@user3487866将数组项放在单独的表中如何?