简体   繁体   English

postgres-更新jsonb数组的语法

[英]postgres - syntax for updating a jsonb array

I'm struggling to find the right syntax for updating an array in a jsonb column in postgres 9.6.6 我正在努力寻找正确的语法来更新Postgres 9.6.6中的jsonb列中的数组

Given a column "comments", with this example: 在此示例中,给定一列“评论”:

[
  {
    "Comment": "A",
    "LastModified": "1527579949"
  },
  {
    "Comment": "B",
    "LastModified": "1528579949"
  },
  {
    "Comment": "C",
    "LastModified": "1529579949"
  }
]

If I wanted to append Z to each comment (giving AZ, BZ, CZ). 如果我想在每个注释后面加上Z(给AZ,BZ,CZ)。

I know I need to use something like jsonb_set(comments, '{"Comment"}', 我知道我需要使用jsonb_set(comments, '{"Comment"}',

Any hints on finishing this off? 有任何完成建议吗?

Thanks. 谢谢。

Try: 尝试:

UPDATE elbat
       SET comments = array_to_json(ARRAY(SELECT jsonb_set(x.original_comment,
                                                           '{Comment}',
                                                           concat('"',
                                                                  x.original_comment->>'Comment',
                                                                  'Z"')::jsonb)
                                                 FROM (SELECT jsonb_array_elements(elbat.comments) original_comment) x))::jsonb;

It uses jsonb_array_elements() to get the array elements as set, applies the changes on them using jsonb_set() , transforms this to an array and back to json with array_to_json() . 它使用jsonb_array_elements()来获得的数组元素作为组,使用施加在其上的改变jsonb_set()这变换到一个数组并返回到jsonarray_to_json()

But that's an awful lot of work. 但这是一项艰巨的工作。 OK, maybe there is a more elegant solution, that I didn't find. 好的,也许有一个更好的解决方案,我没有找到。 But since your JSON seems to have a fixed schema anyway, I'd recommend a redesign to do it the relational way and have a simple table for the comments plus a linking table for the objects the comment is on. 但是由于您的JSON似乎始终具有固定的架构,因此我建议您重新设计以关系方式进行操作,并为注释添加一个简单的表,并为注释所在的对象提供一个链接表。 The change would have been very, very easy in such a model for sure. 当然,在这样的模型中,更改本来非常非常容易。

Find a query returning the expected result: 查找一个返回预期结果的查询:

select jsonb_agg(value || jsonb_build_object('Comment', value->>'Comment' || 'Z'))
from my_table
cross join jsonb_array_elements(comments);

                                                                      jsonb_agg                                                                      
-----------------------------------------------------------------------------------------------------------------------------------------------------
 [{"Comment": "AZ", "LastModified": "1527579949"}, {"Comment": "BZ", "LastModified": "1528579949"}, {"Comment": "CZ", "LastModified": "1529579949"}]
(1 row) 

Create a simple SQL function based of the above query: 根据上述查询创建一个简单的SQL函数:

create or replace function update_comments(jsonb)
returns jsonb language sql as $$
    select jsonb_agg(value || jsonb_build_object('Comment', value->>'Comment' || 'Z'))
    from jsonb_array_elements($1)
$$;

Use the function: 使用功能:

update my_table
set comments = update_comments(comments);

DbFiddle. DbFiddle。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM