11

我正在尝试使用“新”JSONB 类型。

我有一个documents带有propertiesjsonb 字段的表,其中是一个 field publication_year。我想查找一年范围内的所有文档记录,例如 2013-2015。 [编辑:查询一系列值是这里的主要挑战,即使我在下面使用了完全匹配的示例。所要求的方法也适用于美元范围(价格 > 20 美元和价格 < 40 美元)或时间戳范围)。]

我努力了:

create index test1 on documents using gin ((cast(properties->'announced_on_year' as integer)));

ERROR:  cannot cast type jsonb to integer

也:

create index test1 on documents using gin (cast(properties->>'publication_year' as integer));

ERROR:  data type integer has no default operator class for access method "gin"
HINT:  You must specify an operator class for the index or define a default operator class for the data type.`

我从这篇文章http://www.postgresql.org/message-id/10736.1409063604@sss.pgh.pa.us看到这应该是可能的,但我无法弄清楚正确的语法。

当我只是做一个简单的索引时:

create index test1 on documents using gin ((properties->'publication_year'));

创建了一个索引,但我无法使用整数值查询它来获得一个范围,它说

select count(*) from documents where properties->>'publication_year' = 2015;
ERROR:  operator does not exist: text = integer
LINE 1: ...*) from documents where properties->>'publication_year' = 2015;
                              ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

任何提示和提示都非常感谢。我相信其他人也会受益。TIA

4

4 回答 4

6

根据我的经验,我发现在 JSONB 列上使用 GIN 索引并没有更快。您可以通过将其转换为整数来创建普通索引

CREATE INDEX test1 ON documents ((properties->>'publication_year')::int);

此外,GIN 有一些限制,在创建之前应该考虑这些限制。即使对整个 JSONB 列进行索引也会产生大量表大小的索引。

这是基于我的经验并查看 Postgres 文档。

于 2017-03-21T15:28:39.810 回答
3

1)整数没有 GIN 索引(至少不是开箱即用的),使用 btree。

create index test1 on documents using btree (cast (properties->>'announced_on_year' as int));

2)错误是不言自明的,将整数转换为文本或使用文本进行比较:

select count(*) from documents where properties->>'publication_year' = '2015';
于 2015-03-22T16:23:08.400 回答
2

您可以转换为整数并使用 contrib/btree_gin 扩展。

创建扩展 btree_gin;
使用 gin( cast (jb->>'price' as int)) 在 tt 上创建索引 tt_jb_int_idx;
解释分析 select * from tt where cast(jb->>'price' as int) > 3 and cast(jb->>'price' as int) > 'price'::text))::integer > 3) AND (((jb ->> 'price'::text))::integer Bitmap Index Scan on tt_jb_int_idx (cost=0.00..28.06 rows=6 width=0) (实际时间=0.016..0.016 rows=1 loops= 1)
         索引条件:((((jb ->> 'price'::text))::integer > 3) AND (((jb ->> 'price'::text))::integer
于 2017-02-17T13:47:52.647 回答
1

你为什么不为整个jsonb字段定义一个索引,如文档中所述

create index test1 on documents using gin (properties);
于 2015-03-22T16:47:57.440 回答