附加在jsonb数组中,并根据键更新现有记录

时间:2018-07-28 11:08:39

标签: postgresql jsonb postgresql-9.5

我有一个表 media ,其中的jsonb数组字段为 pictures ,其中包含一个空数组。

这个想法是,每当我添加一个新的json对象时,我都希望将默认属性从任何以前的属性从true切换为false。

样本对象:

{"file": "file.jpg", "default": true}

我通过2个不同的查询来实现这一目标。

用于插入新记录的一个:

update media
set pictures = jsonb_set(
    pictures,
    concat('{' , jsonb_array_length(pictures) , '}')::text[],
    jsonb_build_object('file', 'somepicture.jpg', 'default', true)
)
where user_id = 8

一种用于从默认:true 切换到默认:false

的选项
update media
set pictures =
(
    select
        jsonb_agg(
            case when value->>'default' = 'true' and value->>'file' != 'somepicture.jpg'
            then value || jsonb_build_object('default', false)
            else value
            end
        )
    from jsonb_array_elements(media.pictures)
)
where user_id = 8

我的最终照片阵列:

[
 {
  "file": "previouspicture.jpg",
  "default": false
 },
 {
  "file": "somepicture.jpg",
  "default": true
 }
]

仅凭一个查询如何实现同一目的?

1 个答案:

答案 0 :(得分:0)

使用额外的jsonb_set()更新前一个对象。您必须使用coalesce()才能以空数组开头:

update media
set pictures = jsonb_set(
    coalesce(
        jsonb_set(
            pictures,
            array[(jsonb_array_length(pictures)-1)::text],
            pictures->jsonb_array_length(pictures)-1 || '{"default": false}'
            ), 
        pictures
    ),
    array[(jsonb_array_length(pictures))::text],
    jsonb_build_object('file', 'filename.jpg', 'default', true)
)
where user_id = 8
returning *;

DbFiddle.