我在postgresql 9.4数据库中有一个表,其中有一个名为receivers的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}]

我有一个id值列表,希望在jsonb字段的数组中 Select 任何一行,该行包含一个具有该列表中任何值的对象.

可能吗?我能做一个杜松子wine 指数来加速吗?

推荐答案

没有单一的操作可以帮助您,但您有几个 Select :

1.如果要查询的ID数量较少(且固定),可以使用多个包含运算符@>or;f、 例:

where data @> '[{"id": "1884595530"}]' or data @> '[{"id": "791712670"}]'

一个简单的gin索引可以帮助你在这里的数据列.

2.若你们有可变数量的id(或者你们有很多),你们可以用json[b]_array_elements()来提取数组的每个元素,建立一个id列表,然后用任何包含操作符?|来查询它:

select *
from   jsonbtest
where  to_json(array(select jsonb_array_elements(data) ->> 'id'))::jsonb ?|
         array['1884595530', '791712670'];

不幸的是,您无法为表达式编制索引,因为其中包含子查询.如果要为其编制索引,需要为其创建一个函数:

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));

之后,您可以像这样查询ID:

select *, jsonbtest.idlist_jsonb
from   jsonbtest
where  jsonbtest.idlist_jsonb ?| array['193623800', '895207852'];

Note:我这里用了dot notation / computed field,但你不必.

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));

并使用重叠数组运算符&&查询该计算字段:

select *, jsonbtest.idlist_array
from   jsonbtest
where  jsonbtest.idlist_array && array['193623800', '895207852'];

Note:从我的内部测试来看,后一种解决方案的计算成本高于jsonb变体,但实际上它比jsonb变体快一点.如果性能对你来说真的很重要,你应该同时测试这两种性能.

Postgresql相关问答推荐

在PL/pgSQL中使用循环时缓存

使用regexp获取表名

如何在Common Lisp中使用Postmodern在表更改时获得通知?

如何在PSQL中查询jsonb列包含字符串的嵌套数组

使用pg_repack从PostgreSQL中的表中删除OID

在Postgres中如何连接具有相同名称列的表并更改列名称?

IF 块中的 CREATE FUNCTION 语句抛出错误,同时运行它自己的作品

如何在postgresql中按时间查询

从 PostgreSQL 中的每个组中抽取 N 个样本

查找最小值和最大值

PostgreSQL - 改变数字的精度?

断言错误:Django-rest-Framework

psql:致命:connection requires a valid client certificate

在PostgreSQL中 Select 数组列的总和

从 PostgreSQL 中的时间戳获取日期

如何在 PostgreSQL 中插入多行

理解 Postgres 行大小

当从 Heroku pg:pull 数据库时提示:role "root" does not exist.

Android 的 JDBC 与 Web 服务

重命名 Amazon RDS 主用户名