postgres - 更新jsonb数组的语法

时间:2018-06-03 16:01:53

标签: postgresql jsonb

我很难在postgres 9.6.6中的jsonb列中找到更新数组的正确语法

给出一个专栏"评论",用这个例子:

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

如果我想在每条评论中附加Z(给予AZ,BZ,CZ)。

我知道我需要使用像jsonb_set(comments, '{"Comment"}',

这样的东西

关于完成此任务的任何提示?

感谢。

2 个答案:

答案 0 :(得分:1)

尝试:

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;

使用jsonb_array_elements()将数组元素设置为已设置,使用jsonb_set()对其应用更改,将其转换为数组并使用json返回array_to_json()

但那是一项非常繁重的工作。好吧,也许有一个更优雅的解决方案,我没有找到。但是因为你的JSON似乎还有一个固定的模式,我建议重新设计一个关系方式,并为注释添加一个简单的表,以及注释对象的链接表。在这样的模型中,这种变化肯定非常非常容易。

答案 1 :(得分:1)

查找返回预期结果的查询:

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) 

根据上述查询创建一个简单的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)
$$;

使用功能:

update my_table
set comments = update_comments(comments);

DbFiddle.