【问题标题】:How to index select keys in Postgres jsonb data?如何索引 Postgres jsonb 数据中的选择键?
【发布时间】:2018-03-22 16:03:57
【问题描述】:

我在 Postgres 中使用 jsonb 类型来存储键值文档。我在这些文档之上使用 GIN 索引进行快速查找。所有这些都运行良好,尽管默认情况下 GIN 索引往往很冗长,即它们索引 jsonb 结构中的每个键。我想要更有选择性的索引。

GIN 索引可以做到这些吗?

  1. GIN 是否只为顶级键编制索引,而嵌套结构不编制索引?或
  2. 只有 GIN 索引特定的关键字(我知道我可以为每个需要索引的关键字创建单独的 btree 索引。我很想知道我是否可以通过 GIN 完成它)

谢谢。

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    可以使用辅助函数来完成,该函数将 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

    【讨论】:

    • 向小提琴添加更多数据?所以它会开始使用你的索引?否则演示不起作用:)
    • @VaoTsun 有效点,但使索引符合条件的关键是在查询过滤器中使用 索引表达式 :)
    猜你喜欢
    • 1970-01-01
    • 2021-05-20
    • 2019-03-21
    • 2017-02-20
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多