我在Postgres中使用jsonb类型来存储键值文档。我在这些文档的顶部使用GIN索引来快速查找。所有这些都很有效,尽管默认情况下GIN索引往往是冗长的,即它们索引jsonb结构中的每个键。我想有更多的选择性索引。
是否可以使用GIN索引执行这些操作?
谢谢。
答案 0 :(得分:2)
可以使用辅助函数来完成,该函数将JSONB文档作为输入和键数组,并返回一个过滤了键的新文档,然后可以使用GIN进行索引:
create function jsonb_filter(doc jsonb, variadic keys text[])
returns jsonb
as 'select jsonb_object_agg(key, doc->key) from unnest(keys) key'
language sql
immutable;
create index filtered_index on jsonb_table
using gin (jsonb_filter(data, 'a', 'b'));
select data->'a'
from jsonb_table
where jsonb_filter(data, 'a', 'b') @> '{"a":1}';
您可能希望对要在功能内部过滤的键组进行硬编码,以避免在查询中重复这些键。
如果您只想索引某些键的状态,那么:
create function jsonb_keys(doc jsonb)
returns text[]
as 'select array_agg(key) from jsonb_object_keys(doc) key'
language sql
immutable;
create index keys_index on jsonb_table
using gin (jsonb_keys(data));
select data->'b'
FROM jsonb_table
where jsonb_keys(data) @> ARRAY['a'];
可以修改函数jsonb_keys
以仅包含要索引的键。
以下是相关的SqlFiddle http://sqlfiddle.com/#!17/b7935/6