如何查询 JSONB 字段字典中的值数组?

How to query an array of values within a JSONB field dictionary?

我有一个 jsonb 列,其中包含一个字典,该字典有一个指向字符串值数组的键。我需要查询那个数组。

table(称为 "things")看起来像这样:

------------------
| my_column      |
|----------------|
| { "a": ["X"] } |
------------------

我需要写两个查询:

数组是否包含值"X"?

数组是否不包含值"X"?

my_column 有一个非空约束,但它可以包含一个空字典。该词典还可以包含其他 key/value 对。

第一个查询很简单:

SELECT * FROM things
  WHERE my_column -> 'a' ? 'X';`

事实证明,第二个更具挑战性。我从那里开始:

SELECT * FROM things
  WHERE NOT my_column -> 'a' ? 'X';

...但这排除了所有具有不包含关键字 'a' 的字典的记录。所以我这样修改它:

SELECT * FROM things
  WHERE my_column -> 'a' IS NULL OR NOT
        my_column -> 'a' ? 'X';

这个有效,但是有更好的方法吗?另外,是否可以索引此查询,如果可以,如何索引?

我不确定是否有更好的方法 -- 老实说,这对我来说非常简单。

至于索引,您可以做几件事。

首先,你可以index the jsonb field。在该字段上放置 GIN 索引应该有助于使用 "exists" 类型的运算符(如 ?)。

如果出于某种原因这不是您想要的解决方案,Postgres 支持功能索引和 partial 索引。功能索引可能如下所示:

CREATE INDEX ON things ( my_column -> 'a' );

(注意:看起来 postgres 在使用该语法时遇到了问题,这可能是一个错误。不过这个概念成立。)

部分索引会变得更加具体,甚至可能看起来像:

CREATE INDEX ON things (my_column)
  WHERE my_column -> 'a' IS NULL OR NOT
    my_column -> 'a' ? 'X';

显然,这对更一般的查询没有帮助。

猜测,使用 GIN 索引对整个列进行索引是正确的方法,或者至少是正确的起点。