如何在Postgres中查询深jsonb?

时间:2018-05-25 08:45:21

标签: postgresql

我在Postgres中有一个jsonb列(名为info),其结构如下所示:

{ 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_idattr_value

现在,查询具有infoextra_attrs attr_id attr_value的{​​{1}}的最佳方法是什么。我这样做了,它的确有效:

给出以下要查询的数据结构:

[{ 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" }]}

我想知道是否有更好的方法可以这样做,或者这很好。

1 个答案:

答案 0 :(得分:0)

另一种方法是json functions并转换数据以应用过滤器:

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对只在一个地方添加。

类似(也许稍快一点)的方法会使用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" }'
              ]
       )
)