Как запросить массив значений в словаре полей JSONB? - PullRequest
0 голосов
/ 11 января 2019

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

Таблица (называемая «вещами») выглядит следующим образом:

------------------
| my_column      |
|----------------|
| { "a": ["X"] } |
------------------

Мне нужно написать два запроса:

Содержит ли массив значение "X"?

Не содержит ли массив значение "X"?

my_column имеет ненулевое ограничение, но может содержать пустой словарь. Словарь может также содержать другие пары ключ / значение.

Первый запрос был прост:

SELECT * FROM things
  WHERE my_column -> 'a' ? 'X';`

Второй оказывается более сложным. Я начал там с:

SELECT * FROM things
  WHERE NOT my_column -> 'a' ? 'X';

... но это исключало все записи, в которых были словари, в которых не было ключа 'a' Поэтому я изменил это так:

SELECT * FROM things
  WHERE my_column -> 'a' IS NULL OR NOT
        my_column -> 'a' ? 'X';

Это работает , но есть ли лучший способ? Кроме того, возможно ли проиндексировать этот запрос, и если да, то как?

1 Ответ

0 голосов
/ 12 января 2019

Я не уверен, что есть какой-то лучший способ - это, честно говоря, выглядит довольно просто для меня.

Что касается индексации, есть пара вещей, которые вы можете сделать.

Во-первых, вы можете проиндексировать поле jsonb . Помещение индекса GIN в это поле должно помочь при любом использовании операторов типа «существующий» (например, ?).

Если это не то решение, которое вам нужно по какой-либо причине, Postgres поддерживает функциональные и частичные индексы. Функциональный индекс может выглядеть следующим образом:

CREATE INDEX ON things ( my_column -> 'a' );

(примечание: похоже, у postgres возникли проблемы с этим синтаксисом, что может быть ошибкой. Однако концепция верна).

Частичный индекс станет еще более конкретным и даже может выглядеть следующим образом:

CREATE INDEX ON things (my_column)
  WHERE my_column -> 'a' IS NULL OR NOT
    my_column -> 'a' ? 'X';

Очевидно, что это не поможет для более общих запросов.

Можно предположить, что индексирование всего столбца с помощью индекса GIN - это правильный путь или, по крайней мере, правильное место для начала.

...