Как обновить узел JSON, который соответствует критериям на основе значения атрибута (вместо индекса)?

Постгрес 10+

Пример из документации...

jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false)

приводит к...

[{"f1":[2,3,4],"f2":null},2,null,3]

Справедливо. Но мне нужно найти целевой узел по значению атрибута, а не по индексу. На всю жизнь я не могу понять, как сделать что-то вроде...

jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{(where f1 = 1),f1}','[2,3,4]', false)

Любые советы о том, как это сделать? Спасибо!


person Jim Ott    schedule 22.08.2018    source источник


Ответы (1)


Вы можете разделить шаги на две работы:

  1. Разделить на элементы (jsonb_arral_elements)
  2. Определите, какие элементы должны измениться (случай, когда...)
  3. Обновите этот элемент (jsonb_set)
  4. Присоединяйтесь все вместе (jsonb_agg)

решение

select jsonb_agg(case when element->>'f1'='1' then jsonb_set(element, '{f1}', '[2,3,4]') else element end)
  from jsonb_array_elements('[{"f1":1,"f2":null},2,null,3,{"f1":3},{"f1":1,"f2":2}]'::jsonb) element

примечание

Я изменил ввод, добавив еще два элемента с помощью клавиши «f1».

person Emilio Platzer    schedule 22.08.2018
comment
Благодарю за ваш ответ. Это действительно меняет json, однако я не вижу, что он предоставляет средства для обновления записи. Может быть, это моя вина, что я не дал понять, что это то, что мне нужно. Поправьте меня, если я ошибаюсь, но мне кажется, что я должен получить индекс элемента, чтобы изменить элемент, сохранив при этом весь узел. Ссылка, размещенная @klin, работает. Немного многословно и запутанно, но пока единственное, что работает для меня. - person Jim Ott; 22.08.2018
comment
@JimOtt, вы можете использовать его в заявлении об обновлении. См. на: rextester.com/BLC52070 - person Emilio Platzer; 22.08.2018