如何索引jsonb整数值

时间:2015-03-22 16:12:56

标签: postgresql indexing gin jsonb

我试图使用" newish" JSONB类型。

我有一个带有documents jsonb字段的properties表,其中包含一个字段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 个答案:

答案 0 :(得分:3)

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

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

此外,GIN在创建之前应考虑一些limitations。即使索引整个JSONB列也可能导致大量的表大小索引。

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

create extension btree_gin;
create index tt_jb_int_idx on tt using gin( cast (jb->>'price' as int));
explain analyze 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) (actual time=0.016..0.016 rows=1 loops=1)
         Index Cond: ((((jb ->> 'price'::text))::integer > 3) AND (((jb ->> 'price'::text))::integer 

答案 3 :(得分:1)

为什么不为整个 jsonb 字段as described in the doc定义索引?

create index test1 on documents using gin (properties);