Как запросить глубокий JSONB в Postgres? - PullRequest
0 голосов
/ 25 мая 2018

У меня есть столбец jsonb (называемый info) в Postgres, структура которого выглядит следующим образом:

{ name: 'john', house_id: null, extra_attrs: [{ attr_id: 4, attr_value: 'a value' }, { attr_id: 5, attr_value: 'another value' }] }

Он может иметь N extra_attrs, но мы знаем, что у каждого из них будет всего два ключа: attr_id и attr_value.

Теперь, каков наилучший способ запроса info, который имеет extra_attrs с конкретными attr_id и attr_value.Я сделал это так, и это работает:

Учитывая следующую структуру данных для запроса:

[{ attr_id: 4, values: ['a value', 'something else'] }, { attr_id: 5, values: ['another value'] }]

Следующий запрос работает:

select * from people
where (info @> '{"extra_attrs": [{ "attr_id": 4, "attr_value": "a value" }]} OR info @> '{"extra_attrs": [{ "attr_id": 4, "attr_value": "something else" }]) AND info @> '{"extra_attrs": [{ "attr_id": 5, "attr_value": "another value" }]}

Iмне интересно, есть ли лучший способ сделать это, или это нормально.

1 Ответ

0 голосов
/ 25 мая 2018

Один альтернативный метод будет включать функции json и преобразование данных для применения фильтра:

SELECT people.info
FROM people,
LATERAL (SELECT DISTINCT True is_valid
         FROM jsonb_array_elements(info->'extra_attrs') y
         WHERE (y->>'attr_id', y->>'attr_value') IN (
             ('4', 'a value'), 
             ('4', 'something else'),
             ('5','another value')
         )
) y
WHERE is_valid

Я считаю, что этот метод более удобен для динамических фильтров, поскольку пары id / valueдобавлено только в 1 месте.

Аналогичный (и, возможно, немного более быстрый) метод будет использовать WHERE EXISTS и сравнивать документы json, как показано ниже.

SELECT people.info
FROM people
WHERE EXISTS (SELECT TRUE 
       FROM jsonb_array_elements(info->'extra_attrs') attrs
       WHERE attrs @> ANY(ARRAY[
           JSONB '{ "attr_id": 4, "attr_value": "a value" }',
           JSONB '{ "attr_id": 4, "attr_value": "something else" }',
           JSONB '{ "attr_id": 5, "attr_value": "another value" }'
              ]
       )
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...