我在postgresql 9.4数据库中有一个表,其中包含一个名为receiver的jsonb字段.一些示例行:
[{"id": "145119603", "name": "145119603", "type": 2}]
[{"id": "1884595530", "name": "1884595530", "type": 1}]
[{"id": "363058213", "name": "363058213", "type": 1}]
[{"id": "1427965764", "name": "1427965764", "type": 1}]
[{"id": "193623800", "name": "193623800", "type": 0}, {"id": "419955814", "name": "419955814", "type": 0}]
[{"id": "624635532", "name": "624635532", "type": 0}, {"id": "1884595530", "name": "1884595530", "type": 1}]
[{"id": "791712670", "name": "791712670", "type": 0}]
[{"id": "895207852", "name": "895207852", "type": 0}]
[{"id": "144695994", "name": "144695994", "type": 0}, {"id": "384217055", "name": "384217055", "type": 0}]
[{"id": "1079725696", "name": "1079725696", "type": 0}]
Run Code Online (Sandbox Code Playgroud)
我有一个id值列表,并希望在jsonb字段的数组中选择包含具有该列表中任何值的对象的任何行.
那可能吗?我可以制作一个GIN索引来加快速度吗?
poz*_*ozs 49
没有单一操作可以帮助您,但您有几个选择:
1.如果你有一个小的(和固定的)数ID的查询,则可以使用多个运营商遏制@>联合or; f.ex:
where data @> '[{"id": "1884595530"}]' or data @> '[{"id": "791712670"}]'
Run Code Online (Sandbox Code Playgroud)
一个简单的gin索引可以在这里帮助您处理数据列.
2.如果你有不同数量的id(或者你有很多),你可以json[b]_array_elements()用来提取数组的每个元素,建立一个id列表,然后用any-containment运算符查询它?|:
select *
from jsonbtest
where to_json(array(select jsonb_array_elements(data) ->> 'id'))::jsonb ?|
array['1884595530', '791712670'];
Run Code Online (Sandbox Code Playgroud)
遗憾的是,您无法索引表达式,该表达式中包含子查询.如果要对其进行索引,则需要为其创建函数:
create function idlist_jsonb(jsonbtest)
returns jsonb
language sql
strict
immutable
as $func$
select to_json(array(select jsonb_array_elements($1.data) ->> 'id'))::jsonb
$func$;
create index on jsonbtest using gin (idlist_jsonb(jsonbtest));
Run Code Online (Sandbox Code Playgroud)
在此之后,您可以像这样查询ID:
select *, jsonbtest.idlist_jsonb
from jsonbtest
where jsonbtest.idlist_jsonb ?| array['193623800', '895207852'];
Run Code Online (Sandbox Code Playgroud)
注意:我在这里使用了点符号/计算字段,但您不必这样做.
3,但在这一点上,你不必坚持用JSON [B]:你有一个简单的文本阵列,它是由PostgreSQL的支持太大.
create function idlist_array(jsonbtest)
returns text[]
language sql
strict
immutable
as $func$
select array(select jsonb_array_elements($1.data) ->> 'id')
$func$;
create index on jsonbtest using gin (idlist_array(jsonbtest));
Run Code Online (Sandbox Code Playgroud)
并使用重叠数组运算符查询此计算字段&&:
select *, jsonbtest.idlist_array
from jsonbtest
where jsonbtest.idlist_array && array['193623800', '895207852'];
Run Code Online (Sandbox Code Playgroud)
注意:从我的内部测试来看,后一种解决方案的计算成本高于jsonb变量,但事实上它比这更快,一点点.如果性能对你很重要,你应该测试两者.
小智 5
我找到解决方法:
where data::text similar to '%("id": "145119603"|"id": "1884595530")%'
| 归档时间: |
|
| 查看次数: |
28776 次 |
| 最近记录: |