Sql 如何在postgres中过滤json任意键的值

Sql 如何在postgres中过滤json任意键的值,sql,json,postgresql,jsonb,Sql,Json,Postgresql,Jsonb,我有一个名为data的jsonb字段的表users。我必须检索数据列中的值与给定字符串匹配的所有用户。例如: user1 = data: {"property_a": "a1", "property_b": "b1"} user2 = data: {"property_a": "a2", "property_b": "b2"} 我想检索任何具有与“b2”匹配的值数据的用户,在本例中为“user2” 你知道如何优雅地做到这一点吗?我可以从所有用户的数据中检索所有密钥并手动创建查询,但这既不快速也

我有一个名为data的jsonb字段的表users。我必须检索数据列中的值与给定字符串匹配的所有用户。例如:

user1 = data: {"property_a": "a1", "property_b": "b1"}
user2 = data: {"property_a": "a2", "property_b": "b2"}
我想检索任何具有与“b2”匹配的值数据的用户,在本例中为“user2”

你知道如何优雅地做到这一点吗?我可以从所有用户的数据中检索所有密钥并手动创建查询,但这既不快速也不优雅

此外,我必须检索匹配的键和值,但首先要做的是。

没有简单的方法

GIN索引可用于高效搜索键或键/值 在大量jsonb文档数据库中出现的对

我的。没有针对所有值的索引。这些可能有不兼容的数据类型!如果不知道所有键的名称,则必须检查每行中的所有JSON值

如果只有两个像您演示的键,或者只有几个熟悉的键,那么仍然很容易:

SELECT *
FROM   users
WHERE  data->>'property_a' = 'b2' OR
       data->>'property_b' = 'b2';
可以通过以下简单的方式支持:

或使用GIN索引:

SELECT *
FROM   users
WHERE  data @> '{"property_a": "b2"}' OR
       data @> '{"property_b": "b2"}'

CREATE INDEX bar_idx ON users USING gin (data jsonb_path_ops);
如果你不知道所有的键名,事情会变得更复杂

您可以使用将所有值卸载到集合中,然后使用ANY构造进行检查:

挑选* 来自用户 其中jsonb‘b2’=任意选择的jsonb_eachdata.value; 或

... 其中“b2”=任意选择jsonb_each_textdata.value; 小提琴

但最后一个没有索引支持。您可以将所有值提取到和数组中,并在该数组上创建表达式索引,然后在查询中使用数组运算符匹配该表达式

相关的:

没有简单的方法

GIN索引可用于高效搜索键或键/值 在大量jsonb文档数据库中出现的对

我的。没有针对所有值的索引。这些可能有不兼容的数据类型!如果不知道所有键的名称,则必须检查每行中的所有JSON值

如果只有两个像您演示的键,或者只有几个熟悉的键,那么仍然很容易:

SELECT *
FROM   users
WHERE  data->>'property_a' = 'b2' OR
       data->>'property_b' = 'b2';
可以通过以下简单的方式支持:

或使用GIN索引:

SELECT *
FROM   users
WHERE  data @> '{"property_a": "b2"}' OR
       data @> '{"property_b": "b2"}'

CREATE INDEX bar_idx ON users USING gin (data jsonb_path_ops);
如果你不知道所有的键名,事情会变得更复杂

您可以使用将所有值卸载到集合中,然后使用ANY构造进行检查:

挑选* 来自用户 其中jsonb‘b2’=任意选择的jsonb_eachdata.value; 或

... 其中“b2”=任意选择jsonb_each_textdata.value; 小提琴

但最后一个没有索引支持。您可以将所有值提取到和数组中,并在该数组上创建表达式索引,然后在查询中使用数组运算符匹配该表达式

相关的:

尝试此查询

SELECT * FROM users
WHERE data::text LIKE '%b2%'
当然,如果您的密钥也包含这样的字符串,它将不起作用。

尝试此查询

SELECT * FROM users
WHERE data::text LIKE '%b2%'
当然,如果您的密钥也包含这样的字符串,那么它将不起作用。

实际上,=将导致错误。可以使用的表单:SELECT*FROM user WHERE data::text(如“%b2%”)将JSON字段转换为纯文本字段的伟大技巧。实际上,=将导致错误。可以使用的表单是:从用户那里选择*数据::文本,如“%b2%”,这是一个很好的技巧,可以将JSON字段转换为一个文本字段。