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

时间:2019-01-11 19:45:00

标签: sql postgresql jsonb

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

表(称为“事物”)看起来像这样:

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

我需要编写两个查询:

该数组是否包含值“ X”?

数组不包含值“ X”吗?

my_column具有非null约束,但可以包含空字典。字典也可以包含其他键/值对。

第一个查询很简单:

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

可行,但是还有更好的方法吗?此外,是否可以为该查询建立索引,如果可以,该如何建立索引?

1 个答案:

答案 0 :(得分:1)

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

关于索引编制,您可以做几件事。

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

如果出于某种原因这不是您想要的解决方案,则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索引对整个列进行索引是正确的方法,或者至少是正确的起始位置。