Как сообщает telegram-канал Cross Join, в репозиторий Postgres упал комит, упрощающий работу с jsonb. Теперь можно обращаться к частям jsonb с помощью квадратных скобок, причем это работает как на чтение, так и на запись.
Прощай jsonb_set и прочие костыли типа data = data - 'a' || '{"a":5}'
Несколько примеров:
Обновляем значение объекта по ключу. 25 здесь является числом, но взято в кавычки, потому что присваиваемое значение должно быть jsonb
-- (person_data имеет тип jsonb)
UPDATE users
SET person_data['age'] = '25';
Обновление работает и с пустыми (null) jsonb.
Фильтруем таблицу по полю name=Pasha. Pasha — строка, но тоже записана в форме jsonb: '"Pasha"', поэтому лишние двойные кавычки
SELECT *
FROM users
WHERE person_data['name'] = '"Pasha"';
Получаем значение объекта по ключу "age"
SELECT ('{"age": 25}'::jsonb)['age'];
Или можно указать длинный путь
SELECT ('{"a": {"b": {"c": 1}}}'::jsonb)['a']['b']['c'];
Элемент массива по индексу
SELECT ('[1, "2", null]'::jsonb)[1];
Ну и самое главное: изменения войдут в postgreSQL 14!
Оригинальная идея синтаксиса принадлежит Олегу Бартунову, реализация — Дмитрий Долгов
Suvitruf
В коммите в примере:
Пишу строку, записывается как число. Это, как по мне, контринтуитивно.
varanio Автор
Тогда нужно писать
'"25"'
sebres
Ага… т.е. когда надо сделать такое как ниже, то нужно будет и далее кастить?
И если вот это вероятно будет работать и без
cast(age as varchar)
(из за нативного неявного преобразования между numeric и varchar):то здесь нужно будет обязательно обернуть в кавычки?
Серьезно?..
Если так, то это несколько сомнительная реализация (как минимум какое-то половинчатое решение)…
Почему нельзя было сделать типизированный implicit cast (implicit conversion)? Ведь если это зарелизят в таком виде, то позже
'25'
на вход json "навсегда" останется numeric (для структур json), и "нормальный" inplace cast (где это varchar а не numeric) уже нельзя будет сделать позже из-за потери совместимости.varanio Автор
наверно надо будет вот так оборачивать (точно не знаю)
sebres
Ну то есть все индексы побоку? fullscan по выражению? :) Тогда уж что-нибудь типа такого:
Только, чем оно лучше того же
->>
тогда? Сформулирую по другому, зачем еще один "странный" сахар для->>
(неее, даже не для->>
а для->
)...Kwisatz
Может быть там nullsafe? Попытка сделать последовательное обращение через указанные вами операторы сдохнет на первой же строке где свойства нет, насколько я помню.