Jua*_*llo 3 sql postgresql json jsonb
我有一个表users有一个jsonb叫场data。我必须检索在该列中具有与给定字符串匹配的值的所有用户data。例如:
user1 = data: {"property_a": "a1", "property_b": "b1"}
user2 = data: {"property_a": "a2", "property_b": "b2"}
Run Code Online (Sandbox Code Playgroud)
我想检索具有data匹配值的任何用户'b2',在本例中为'user2'.
知道如何以优雅的方式做到这一点吗?我可以检索所有data用户的所有密钥并手动创建查询,但这既不快速也不优雅。
此外,我必须检索匹配的键和值,但首先要做的是。
没有简单的方法。根据文档:
GIN 索引可用于有效搜索大量 jsonb 文档(数据)中出现的键或键/值对
大胆强调我的。所有值都没有索引。(那些可能具有不兼容的数据类型!)如果您不知道所有键的名称,则必须检查每一行中的所有 JSON 值。
如果像您演示的那样只有两个键(或只有几个众所周知的键),它仍然很容易:
SELECT *
FROM users
WHERE data->>'property_a' = 'b2' OR
data->>'property_b' = 'b2';
Run Code Online (Sandbox Code Playgroud)
可以通过简单的表达式索引来支持:
CREATE INDEX foo_idx ON users ((data->>'property_a'), (data->>'property_b'))
Run Code Online (Sandbox Code Playgroud)
或者使用 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);
Run Code Online (Sandbox Code Playgroud)
如果你不知道所有的键名,事情会变得更复杂......
您可以使用jsonb_each()或jsonb_each_text()将所有值取消嵌套到一个集合中,然后使用ANY构造进行检查:
SELECT *
FROM users
WHERE data->>'property_a' = 'b2' OR
data->>'property_b' = 'b2';
Run Code Online (Sandbox Code Playgroud)
或者
CREATE INDEX foo_idx ON users ((data->>'property_a'), (data->>'property_b'))
Run Code Online (Sandbox Code Playgroud)
db<>在这里摆弄
但是最后一个没有索引支持。您可以改为将所有值提取到数组中并在其上创建一个表达式索引,并将查询中的该表达式与数组运算符进行匹配...
有关的:
试试这个查询。
SELECT * FROM users
WHERE data::text LIKE '%b2%'
Run Code Online (Sandbox Code Playgroud)
当然,如果您的密钥也包含这样的字符串,它将不起作用。
| 归档时间: |
|
| 查看次数: |
7872 次 |
| 最近记录: |