Postgres jsonb array: query for non-empty intersec

2019-07-02 03:33发布

Suppose I have a JSONB column called value in a table t, and inside of these blobs of JSON is a tags field which is a list of strings.

I'd like to make a query for any of these JSON blobs tagged "foo" or "bar".

So suppose the table data looks like this:

value
---------------------
{"tags": ["other"]}
{"tags": ["foo", "quux"]}
{"tags": ["baz", "bar"]}
{"tags": ["bar", "foo"]}
{"tags": []}

I want to write some sort of query like this:

select value from t where value->'tags' NONEMPTY_INTERSECTION '["foo", "bar"]'

Such that the result will be:

value
-----------------------
{"tags": ["foo", "quux"]}
{"tags": ["baz", "bar"]}
{"tags": ["bar", "foo"]}

Is there an actual query that will accomplish this, and is there any way that it could possibly be fast?

2条回答
冷血范
2楼-- · 2019-07-02 03:57

The operator I was looking for is ?|, which can be used like so:

select t.value from t where value->'tags' ?| array['foo','bar'];

Tested as follows:

danburton=# select * from jsonb_test;
           value
---------------------------
 {"tags": ["foo"]}
 {"tags": ["other"]}
 {"tags": ["foo", "quux"]}
 {"tags": ["baz", "bar"]}
 {"tags": ["bar", "foo"]}
 {"tags": []}
(6 rows)

danburton=# select jsonb_test.value from jsonb_test where value->'tags' ?| array['foo','bar'];
           value
---------------------------
 {"tags": ["foo"]}
 {"tags": ["foo", "quux"]}
 {"tags": ["baz", "bar"]}
 {"tags": ["bar", "foo"]}
(4 rows)
查看更多
一夜七次
3楼-- · 2019-07-02 04:15
SELECT DISTINCT t.value
FROM t, jsonb_array_elements(t.value->'tags') tags
WHERE tags.value <@ '["foo", "bar"]'::jsonb;
查看更多
登录 后发表回答