【问题标题】:Indexing on jsonb keys in postgresql在 postgresql 中对 jsonb 键进行索引
【发布时间】:2020-09-25 18:42:13
【问题描述】:

我正在使用 PostgreSQL。 有什么方法可以创建索引 只在字典键上,而不是值上

例如想象一个 jsonb 列,如:

select data from tablename where id = 0;

answer: {1:'v1', 2:'v2'}

我想索引[1, 2] 的键集(或键列表)。加快查询速度,例如:

select count(*) from tablename where data ? '2';

正如您在docs 中看到的,有一种方法可以完全索引列(键 + 值):

CREATE INDEX idxgin ON api USING GIN (jdoc);

考虑到我将大量数据存储在值中,这对我不利。

我以前试过这个:

CREATE INDEX test ON tablename (jsonb_object_keys(data));

错误是:

ERROR:  set-returning functions are not allowed in index expressions

另外,我不想将字典中的键作为值存储。

你能帮帮我吗?

【问题讨论】:

  • 创建索引以支持查询。您必须向我们展示您希望使用该索引支持哪种查询(where 条件)。例如您拥有的索引将支持where data ? '1'
  • 使用where data ? '?'
  • 再次声明:该条件可以利用列上的 gin 索引。
  • 啊哈。我可以请你告诉我在命令中写什么吗? CREATE INDEX 测试表名(数据?);像那样?
  • ِ是的。但这会索引所有对我来说不愉快的数据(键+值)。我只想索引键。

标签: postgresql indexing jsonb


【解决方案1】:

您的示例没有多大意义,因为您的 WHERE 子句未指定 JSON 操作,并且您的示例输出不是有效的 JSON 语法。

您可以将返回集合的函数(和聚合)隐藏到 IMMUTABLE 函数中:

create function object_keys(jsonb) returns text[] language SQL immutable as $$ 
    select array_agg(jsonb_object_keys) from jsonb_object_keys($1)
$$;

create index on tablename using gin ( object_keys(data));

如果你这样做了,你就可以这样查询它:

select * from tablename where object_keys(data) @> ARRAY['2'];

您可以改为让函数返回包含数组的 JSONB,而不是返回 PostgreSQL 文本数组,如果您希望以这种方式查询它:

select * from tablename where object_keys_jsonb(data) @> '"2"';

您不能使用? 公式,因为在 JSONB 中,它专门用于对象而不是数组。如果你真的想使用?,你可以改写一个函数,将对象保留为对象,但将所有值转换为 JSON null 或空字符串,因此它们占用的空间更少。

【讨论】:

  • 感谢您的回答。我添加了另一个有问题的查询。该索引是否支持以下查询:'select count(*) from tablename where data? '2';'
猜你喜欢
  • 2020-12-08
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 2020-06-10
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多