繁体   English   中英

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

[英]How to filter a value of any key of json in postgres

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

user1 = data: {"property_a": "a1", "property_b": "b1"}
user2 = data: {"property_a": "a2", "property_b": "b2"}

我想检索具有匹配'b2'data任何用户,在本例中为'user2'

知道如何以优雅的方式做到这一点吗? 我可以从所有用户的data中检索所有键并手动创建查询,但这既不快速也不优雅。

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

没有简单的方法。 根据文档:

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

大胆强调我的。 所有都没有索引。 (那些可能具有不兼容的数据类型!)如果您不知道所有键的名称,则必须检查每一行中的所有 JSON 值。

如果像您演示的那样只有两个键(或只有几个众所周知的键),它仍然很容易:

SELECT *
FROM   users
WHERE  data->>'property_a' = 'b2' OR
       data->>'property_b' = 'b2';

可以通过简单的表达式索引来支持:

CREATE INDEX foo_idx ON users ((data->>'property_a'), (data->>'property_b'))

或者使用 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);

如果你不知道所有的键名,事情会变得更复杂......

您可以使用jsonb_each()jsonb_each_text()将所有值jsonb_each_text()到一个集合中,然后使用ANY构造进行检查:

SELECT *
FROM   users
WHERE  jsonb '"b2"' = ANY (SELECT (jsonb_each(data)).value);

或者

...
WHERE  'b2' = ANY (SELECT (jsonb_each_text(data)).value);

db<> 在这里摆弄

但是最后一个没有索引支持。 您可以改为将所有值提取到数组中并在其上创建一个表达式索引,并将查询中的该表达式与数组运算符进行匹配...

有关的:

试试这个查询。

SELECT * FROM users
WHERE data::text LIKE '%b2%'

当然,如果您的密钥也包含这样的字符串,它将不起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM