我有一个棘手的查询,试图找到将JSON数组列表与列中的JSON值列表进行比较的匹配项
带有“关键字”列的“事物”表将包含以下内容:
'["car", "house", "boat"]'::JSONB
查询将包含以下值:
'["car", "house"]'::JSONB
我想查找清单中包含“汽车”和“房屋”的所有行。这是我(大部分)微弱的尝试:
SELECT
*
FROM
"Things"
WHERE
"Keywords"::JSONB ?| ARRAY(
SELECT * FROM JSONB_ARRAY_ELEMENTS('["house","car"]'::JSONB)
)::TEXT[]
此外,在索引编制方面,我假设添加GIST索引是我的最佳选择。
答案 0 :(得分:1)
我想查找所有同时具有“汽车”和“房屋”的行
所以正确的运算符是?&
-Do all of these array strings exist as top-level keys?
您的查询几乎是正确的,请更改运算符并使用jsonb_array_elements_text()
:
WITH "Things"("Keywords") AS (
VALUES
('["car", "house", "boat"]'::jsonb),
('["car", "boat"]'),
('["car", "house"]'),
('["house", "boat"]')
)
SELECT
*
FROM
"Things"
WHERE
"Keywords" ?& array(
SELECT jsonb_array_elements_text('["house","car"]')
)
Keywords
--------------------------
["car", "house", "boat"]
["car", "house"]
(2 rows)
如果可以将参数记为规则的文本数组,则查询会更简单:
SELECT
*
FROM
"Things"
WHERE
"Keywords" ?& array['house', 'car']
在两种情况下,您都可以使用GIN index:
jsonb的默认GIN运算符类支持使用顶级键存在的运算符?,?&和?|进行查询。运算符(...)