当前位置: 首页 > 面试题库 >

如何使用IN运算符查询jsonb数组

鲜于阳成
2023-03-14
问题内容

我正在寻找一种使用数组中的“ IN”子句查询postgres jsonb字段的方法。

假设我有一张桌子

CREATE TABLE test(
   id uuid,
   test_content jsonb,
   PRIMARY KEY(id)
);

INSERT INTO test (id, test_content) VALUES 
('aa82a8b8-33ef-4937-bd8c-8a4b40960f18', '[{"label":"a","label1":"1"},{"label":"b","label1":"2"}]'),
('ba82a8b8-33ef-4937-bd8c-8a4b40960f18', '[{"label":"c","label1":"3"}]'),
('da82a8b8-33ef-4937-bd8c-8a4b40960f18', '[{"label":"d","label1":"4"}]');

我需要选择test_content数组中的label可能为b或的行d

我试过了

SELECT * 
FROM test 
WHERE test_content @> '[{"label":"b"}]' OR test_content @> '[{"label":"d"}]'

但是当我想用label1包含扩展查询时,2或者3变得复杂…

我需要的是 WHERE label IN ('b','d') AND label1 IN ('2','3')

jsonb运算符可以吗?


问题答案:

简短答案

您可以jsonb_array_elements()在横向联接中使用该函数,并valueWHERE子句中的复杂表达式中使用其结果:

SELECT t.* 
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('b', 'd')
AND value->>'label1' IN ('2', '3')

不同

当在单个行中的多个数组元素中满足过滤条件时,查询可能返回重复的行,例如

SELECT t.* 
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')

                  id                  |                          test_content                          
--------------------------------------+----------------------------------------------------------------
 aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
 aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
(2 rows)

因此DISTINCT,在SELECT列表中使用可能是合理的:

SELECT DISTINCT t.* 
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')

EXISTSWHERE子句中,可能会更快一些:

SELECT t.*
FROM test t
WHERE EXISTS (
    SELECT 
    FROM jsonb_array_elements(test_content)
    WHERE value->>'label' IN ('a', 'b')
    )

在需要此信息的情况下,您也可以选择匹配的数组元素:

SELECT id, value
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')

                  id                  |             value             
--------------------------------------+-------------------------------
 aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "a", "label1": "1"}
 aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "b", "label1": "2"}
(2 rows)

表现

jsonb_array_elements()功能很昂贵。对于较大的表,由于服务器负载沉重且查询执行时间长,该功能的使用可能会令人怀疑。

虽然GIN索引可用于与@>运算符的查询:

CREATE INDEX ON test USING GIN (test_content)

对于该功能,这是不可能的。索引支持的查询可能比使用该函数的查询快几十倍。



 类似资料:
  • 本文向大家介绍postgresql 使用JSONb运算符,包括了postgresql 使用JSONb运算符的使用技巧和注意事项,需要的朋友参考一下 示例 创建数据库和表 填充数据库 让我们看一下表格中的所有内容: 输出: -> 运算符从JSON列中返回值 选择1列: 输出: 选择2列: 输出: -> 与 ->> 该->运算符返回原始JSON类型(可能是一个对象),而->>返回文本。 返回嵌套对象

  • 问题是我得到错误(过滤器表达式只能包含非主键属性:主键属性:名称)。租户是我的主分区键,名称是我的主排序键。 我需要在dynamo db中编写与此等效的内容:从项目中选择*,其中tenant='testProject',name in('John','Dave')。

  • 我有一张名为产品的桌子。它的架构是 CustomerNumber(字符串类型的哈希键) ProductID(字符串类型的范围键) > DynamodbQueryExpression将只对索引/hashkey进行查询,而不是对hashkey列表进行查询,如上例所示。 此外,DynamoDBQueryExpression不支持OR运算符。 另外,BatchLoad只使用主键(在我的例子中是custom

  • 我不能使用操作符“and”执行查询,无论是使用筛选器还是查询。 http://www.elasticsearch.org/guide/reference/query-dsl/bool-query/ http://www.elasticsearch.org/guide/reference/query-dsl/and-filter/ 我试过: 会产生以下错误的: 我也试过: 此查询不返回错误消息,但它

  • 问题内容: 通配符*只能在单词的末尾使用,例如。 我想用like查询,该怎么做? 问题答案: Lucene提供了ReverseStringFilter,它允许执行通配符搜索,例如* user。它通过以相反顺序索引所有术语来工作。 但是我认为没有办法做类似’LIKE%user%’的事情。

  • 问题内容: 我有和数组两个值,我想在选择查询中将它与sql IN运算符一起使用。 这是我桌子的结构 我有两个值的数组 我想获取comp_id 1和comp_id 2的记录。因此,我编写了以下查询。 但是它不会返回结果。 问题答案: 由于您拥有普通 整数 就可以做到… (由于不断出现,一些其他信息…) 如果使用 字符串 (特别是 不受信任的 )输入,可以做到 但不能处理NULL之类的值。并会添加引号