我在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_id
和attr_value
。
现在,查询具有info
和extra_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" }]}
我想知道是否有更好的方法可以这样做,或者这很好。
答案 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" }'
]
)
)