列的JSONB数组中存在JSON的值

时间:2018-07-04 12:35:35

标签: json postgresql jsonb

我有一个棘手的查询,试图找到将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索引是我的最佳选择。

1 个答案:

答案 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运算符类支持使用顶级键存在的运算符?,?&和?|进行查询。运算符(...)