Добавление нового элемента в массив Json - PullRequest
0 голосов
/ 27 февраля 2019

Я хочу добавить новый элемент массива в a3 ниже json:

{
    "a1": "e1",
    "a2": {
        "b1": "y1",
        "b2": "y2"
    },
    "a3": [{
            "arr1": "1"
        },
        {
            "arr2": "2"
        }
    ]
}

Поэтому я хочу, чтобы выше json был таким:

{
    "a1": "e1",
    "a2": {
        "b1": "y1",
        "b2": "y2"
    },
    "a3": [{
            "arr1": "1"
        },
        {
            "arr2": "2"
        },
        {
            "arr3": "3"
        }
    ]
}

Я могу добавить новыйэлемент с командой ниже.Но когда дело доходит до массива, я не могу найти способ добавить новый элемент.

SELECT jsonb_set('{ "a1": "e1", "a2": { "b1": "y1", "b2": "y2" }, "a3": [{ "arr1": "1" }, { "arr2": "2" }] }'::jsonb,
'{a2,b3}', 
'"4"');

Какую команду я могу использовать, чтобы добавить {"arr3": "3"} к a3?

edit: если arr3 уже существует, команда должна изменить свое значение.Не следует добавлять дубликаты {"arr3": "3"}.

1 Ответ

0 голосов
/ 27 февраля 2019

Использование оператора конкатенации || для массива:

with my_data(json_data) as (
values
    ('{ "a1": "e1", "a2": { "b1": "y1", "b2": "y2" }, "a3": [{ "arr1": "1" }, { "arr2": "2" }] }'::jsonb)
)

select jsonb_set(json_data, '{a3}', json_data->'a3' || '{"arr3": "3"}')
from my_data;

                                             jsonb_set                                             
---------------------------------------------------------------------------------------------------
 {"a1": "e1", "a2": {"b1": "y1", "b2": "y2"}, "a3": [{"arr1": "1"}, {"arr2": "2"}, {"arr3": "3"}]}
(1 row)

Проверка наличия ключа во вложенном массиве немного сложна.Чтобы сделать это, вы должны удалить массив с помощью jsonb_array_elements():

with my_data(json_data) as (
values
    ('{ "a1": "e1", "a2": { "b1": "y1", "b2": "y2" }, "a3": [{ "arr1": "1" }, { "arr2": "2" }] }'::jsonb)
)

select 
    case when already_exists then json_data
    else jsonb_set(json_data, '{a3}', json_data->'a3' || '{"arr3": "3"}')
    end as json_data
from (
    select json_data, bool_or(value ? 'arr3') as already_exists
    from my_data
    cross join jsonb_array_elements(json_data->'a3')
    group by 1
    ) s
...