postgres - синтаксис для обновления массива jsonb - PullRequest
0 голосов
/ 03 июня 2018

Я изо всех сил пытаюсь найти правильный синтаксис для обновления массива в столбце jsonb в postgres 9.6.6

Учитывая столбец "комментарии", в этом примере:

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

Если бы я хотел добавить Z к каждому комментарию (давая AZ, BZ, CZ).

Я знаю, что мне нужно использовать что-то вроде jsonb_set(comments, '{"Comment"}',

Любые подсказки по завершению этого?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

Найти запрос, возвращающий ожидаемый результат:

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.

0 голосов
/ 03 июня 2018

Попробуйте:

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 в любом случае имеет фиксированную схему, я бы порекомендовал изменить дизайн, чтобы сделать это реляционным способом и иметь простую таблицу для комментариев плюс таблицу ссылок для объектов, к которым относится комментарий.Изменение было бы очень и очень легко в такой модели наверняка.

...