DevGang
Авторизоваться

Как обновить объекты внутри массивов JSONB с помощью PostgreSQL 

Допустим, вы решили сохранить данные в базе данных как json или jsonb и обнаружили, что вы просто создали для себя новые проблемы, которых у вас не было раньше. Ты не одинок.

JSONB - это мощный инструмент, но он требует определенных затрат, потому что вам нужно адаптировать способ запроса и обработки данных.

И нередко загружать весь объект jsonb в память, преобразовывать его, используя предпочитаемый вами язык программирования, а затем сохранять его обратно в базу данных. Но вы только что создали еще одну проблему: узкие места в производительности и растрата ресурсов.

В этой статье мы рассмотрим, как обновить конкретное значение объекта внутри массива одним запросом.

Финальный запрос находится в конце статьи, и вы можете посмотреть живой пример на DB Fiddle, чтобы скопировать, вставить и поиграться с ним.

Предположим, вы используете экран клиента для хранения динамических контактов для каждого клиента. Затем у вас возникает идея сохранить контакты в виде столбца JSONB, потому что они динамические, и, таким образом, использование нереляционной структуры данных имеет смысл.

Затем вы создаете таблицу клиентов со столбцом контактов JSONB и вставляете в нее некоторые данные:

Довольно легко, верно? Но как вы можете обновить конкретный контакт для конкретного клиента? Как изменить адрес электронной почты Джими или телефон Яниса? 🤔

К счастью, PostgreSQL - ваш друг и предоставляет функцию jsonb_set :

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

Имея столбец jsonb, вы можете установить новое значение по указанному пути:

Приведенные выше варианты вернут:

[{«Type»: «phone», «value»: «+ 1–202–555–0105»}, {«type»: «email», «value»: «jimi.hendrix@gmail.com»}]
[{«Type»: «email», «value»: «janis.joplin@gmail.com»}]

Чтобы изменить адрес электронной почты Джими в списке контактов, вы указываете путь «1, value», что означает второй объект в массиве (начиная с 0) и value ключа. Это путь. То же самое относится и к изменению электронной почты Яниса, но его почтовый объект имеет индекс 0.

Вы можете подумать: мне просто нужно использовать jsonb_set в операторе обновления, и все готово? Это идея, но этого еще недостаточно.

Проблема с нереляционными данными заключается в том, что они динамические. Ну, это одна из причин использования JSONB, но возникает проблема: убедитесь, что объект электронной почты Jimi имеет индекс 1, а объект электронной почты Janis имеет индекс 0 в массиве, а другой клиент может иметь совсем другой массив с другими индексами. , Итак, как вы можете узнать индекс каждого типа контактов? 🤔

Ответ - упорядочить элементы массива и получить его индекс:

Этот запрос возвращает значение 1, которое является индексом из объекта электронной почты, внутри contact в массиве customers.

Теперь у нас есть все части головоломки: мы знаем, как обновить значение jsonb и как найти индекс обновляемого объекта.

Единственный оставленный шаг - само обновление. Собрав все это вместе, мы имеем:

Наиболее важной частью этого запроса является блок with. Это мощный ресурс, но для этого примера вы можете думать о нем как о «способе хранения переменной», то есть пути контакта, который необходимо обновить, который будет динамическим в зависимости от записи.

Позвольте мне немного пояснить:

(‘{‘||index-1||’,value}’)::text[] as path

Он просто строит путь как '{1, value}' , но нам нужно преобразовать в text[], потому что это тип, ожидаемый в функции jsonb_path .

В заключении

JSONB - это отличный и ценный инструмент для решения множества проблем. Но имейте в виду, что вам также необходимо запрашивать и обновлять данные такого рода. Это приводит к затратам, которые вы должны учитывать при принятии решения о том, какие инструменты вы выберете для использования.

#PostgreSQL
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

Поделитесь своим опытом, расскажите о новом инструменте, библиотеке или фреймворке. Для этого не обязательно становится постоянным автором.

Попробовать

В этом месте могла бы быть ваша реклама

Разместить рекламу