Проблема с оператором jsonb ?
заключается в том, что он рассматривает только ключи верхнего уровня * (включая элементы массива), а не значений и никаких вложенных объектов.
Вы, похоже, ищете значений и элементов массива (не ключи) на любом уровне.Это можно получить с помощью полнотекстового поиска в верхней части столбца json
(b
):
SELECT * FROM tbl
WHERE to_tsvector('simple', jsonb_column)
@@ tsquery '5cbffeb7-8d5e-4b52-a475-3cf320b2cee9';
db <> fiddle здесь
to_tsvector()
извлекает значения и элементы массива на все уровни - именно то, что вам нужно.
Требуется Postgres 10 илипотом.json(b)_to_tsvector()
в Postgres 11 предлагает больше гибкости.
Это привлекательно для таблиц нетривиального размера, так как его можно поддерживать с полным текстом index очень эффективно:
CREATE INDEX tbl_jsonb_column_fts_gin_idx ON tbl USING GIN (to_tsvector('simple', jsonb_column));
Я использую текст 'simple'
поиск конфигурации в примере.Возможно, вы захотите выбрать язык, например 'english'
.Не имеет большого значения, пока вы ищите только строки UUID, но использование для определенного языка может сделать индекс немного меньше ...
Related:
Пока выищите только UUID, вы можете оптимизировать его с помощью пользовательской (IMMUTABLE
) функции для извлечения UUID из документа JSON в виде массива (uuid[]
) и построения функционального индекса GIN поверх него.(Значительно меньший индекс, но.) Тогда:
SELECT * FROM tbl
WHERE my_uuid_extractor(jsonb_column) @> '{5cbffeb7-8d5e-4b52-a475-3cf320b2cee9}';
Такая функция может быть дорогой, но не имеет большого значения с функциональным индексом, который хранит и работает с предварительно вычисленными значениями.