如何查询 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 索引对整个列进行索引是正确的方法,或者至少是正确的起点。
我有一个 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 索引对整个列进行索引是正确的方法,或者至少是正确的起点。