Обновить/Вставить значение в jsonb поле по ключу ( Postgresql )

Update/Insert value inside jsonb array field by key

Схема таблицы

Example table schema:
freeswitch=> \d forms
                              Table "public.forms"
  Column   |  Type   | Collation | Nullable |              Default               
-----------+---------+-----------+----------+------------------------------------
 id        | integer |           | not null | nextval('forms_id_seq1'::regclass)
 form      | text    |           | not null | 
 name      | text    |           | not null | 
 value     | jsonb   |           |          | '{}'::jsonb
 callgroup | text    |           |          | 'default'::text
 enable    | boolean |           |          | false

Исходные данные

Initial value:
freeswitch=> select value->>'info' as info_val from forms;
                                     info_val                                     
----------------------------------------------------------------------------------
 [["Приветствие", "Я представляю компанию..."], ["Инфо№1", "Хочу предложить..."]]
(1 row)

Обновить значение по ключу (jsonb_set)

update value by key "info"
 update forms set value  = jsonb_set(value,'{info}','[["Приветствие", "Добрый день! Звоню из 0вн0Пилюли.."], ["Инфо№1", "Хочу предложить вам наши пилюли из..."]]',true);

Схема запроса

schema of a query

Возвращает значение target, в котором раздел с заданным путём (path) заменяется новым значением (new_value), либо в него добавляется значение new_value, если аргумент create_missing равен true (это значение по умолчанию) и элемент, на который ссылается path, не существует. Как и с операторами, рассчитанными на пути, отрицательные числа в пути (path) обозначают отсчёт от конца массивов JSON.

jsonb_set(target jsonb, path text[], new_value jsonb [, create_missing boolean])

Result:

freeswitch=> select value->>'info' as info_val from forms;
                                                      info_val                                                       
---------------------------------------------------------------------------------------------------------------------
 [["Приветствие", "Добрый день! Звоню из 0вн0Пилюли.."], ["Инфо№1", "Хочу предложить вам наши пилюли из..."]]
(1 row)

Обновить значение во вложенном массиве

Update the value of an included array: '{key,1}'
freeswitch=> update forms set value  = jsonb_set(value,'{info,1}','["Инфо№1", "Хочу предложить наши пилюли из очищенного..."]');
UPDATE 1

result:

freeswitch=> select value->>'info' as info_val from forms;
                                                info_val                                                
--------------------------------------------------------------------------------------------------------
 [["Приветствие", "Добрый день! Звоню из 0вн0Пилюли.."], ["Инфо№1", "Хочу предложить наши пилюли из очищенного..."]]
(1 row)

Обновить значение в массиве вложенном в массив

Update the value of an array included in the array: '{key,0,0}'
freeswitch=> update forms set value  = jsonb_set(value,'{info,0,0}','"Приветствие#1"');
UPDATE 1

Result:

freeswitch=> select value->>'info' as info_val from forms;
                                      info_val                                      
------------------------------------------------------------------------------------
 [["Приветствие#1", "Я представляю компанию..."], ["Инфо№1", "Хочу предложить..."]]
(1 row)

Вставить новое значение в массив (jsonb_insert)

Insert new array value by keys: {info,2}
jsonb_insert(target jsonb, path text[], new_value jsonb [, insert_after boolean])

Возвращает значение target с вставленным в него новым значением new_value. Если место в target, выбранное путём path, оказывается в массиве JSONB, new_value будет вставлен до (по умолчанию) или после (если параметр insert_after равен true) выбранной позиции. Если место в target, выбранное путём path, оказывается в объекте JSONB, значение new_value будет вставлено в него, только если заданный путь path не существует. Как и с операторами, рассчитанными на пути, отрицательные числа в пути (path) обозначают отсчёт от конца массивов JSON.

freeswitch=> update forms set value  = jsonb_insert(value,'{info,2}','["Info#2","We offer pills from purified ..."]');
UPDATE 1
freeswitch=> select value->>'info' as info_val from forms;
                                                              info_val                                                              
------------------------------------------------------------------------------------------------------------------------------------
 [["Приветствие#1", "Я представляю компанию 0вн0Пилюли..."], ["Инфо№1", "Хочу предложить пилюли из очищенного..."], ["Info#2", "We offer pills from purified ..."]]
(1 row)

Вставить между существующими значениями ({info,1} - если четвертый аргумент insert_after = false или отсутствует, то перед элементом 1, если insert_after = true, то после элемента 1)

Insert between positions ({info,1} means before 1 position)
freeswitch=> update forms set value  = jsonb_insert(value,'{info,1}','["Greeting#2","I represent company SheetPills ..."]');
UPDATE 1
freeswitch=> select value->>'info' as info_val from forms;
                                                                                         info_val                                                                                         
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 [["Приветствие#1", "Я представляю компанию..."], ["Greeting#2", "I represent company SheetPills ..."], ["Инфо№1", "Хочу предложить пилюли из очищенного..."], ["Info#2", "We offer pills from purified ..."]]
(1 row)

Удалить из вложенного массива

freeswitch=> select value->>'pick'  from forms;
           ?column?            
-------------------------------
 ["Встреча", "Снято", "Отказ"]
(1 row)

1-й вариант, по индексу:

update forms set value = jsonb_set(value,'{pick}',(value->'pick') - 1);

Результат, удалено значение "Снято" по индексу 1:

freeswitch=> select value->>'pick'  from forms;
       ?column?       
----------------------
 ["Встреча", "Отказ"]
(1 row)

2-й вариант, по значению ("Отказ"):

freeswitch=> update forms set value = jsonb_set(value,'{pick}',(value->'pick') - 'Отказ');
UPDATE 1
freeswitch=> select value->>'pick'  from forms;  
  ?column?   
-------------
 ["Встреча"]

Удалить элемент верхнего уровня при помощи оператора '-'

 select value from forms where id = 2;
                                         value                                         
---------------------------------------------------------------------------------------
 {"info": [], "pick": [], "info2": [], "status": [], "info_adv": [], "objections": []}
(1 строка)
UPDATE forms SET value = value - 'info2'

Вставить новый элемент (ключ) верхнего уровня

update forms set value = jsonb_insert(value,'{info_adv}','[]');

docs:

jsonb functions

  • blog/update_value_inside_jsonb_postgres.txt
  • Последние изменения: 2022/06/07