Postgres jsonb“不包含”运算符

Posted

技术标签:

【中文标题】Postgres jsonb“不包含”运算符【英文标题】:Postgres jsonb 'NOT contains' operator 【发布时间】:2017-02-05 18:13:15 【问题描述】:

我正在尝试使用 postgres jsonb 列类型,到目前为止一切都很好。 我正在使用的一个常见查询是这样的:

select count(*) from jsonbtest WHERE attributes @> '"City":"Mesa"';

我该如何扭转呢?是否有不同的运算符或仅用作

select count(*) from jsonbtest WHERE NOT attributes @> '"City":"Mesa"';

【问题讨论】:

不,没有专门的操作员。 NOT 怎么了? @redneb 问题是NOT 根本不起作用。使用attributes->>'City' <> 'Mesa' 公式也不起作用。 @eykanal NOT works pretty well. 【参考方案1】:

---包含特定键(城市)不包含值('“Mesa”')。

SELECT count(*) FROM jsonbtest  WHERE not (attributes  -> 'City'  @> '"Mesa"');

---不包含特定键值对:"City":"Mesa"

SELECT count(*) FROM jsonbtest  WHERE  NOT (attributes  @> '"City":"Mesa"')

由于属性键可以是 City 之外的其他键。所以这两个查询是不同的!

【讨论】:

【参考方案2】:

两种方式,你可以测试任何 json(b) 值

->> 运算符将值提取为文本。但是这个操作很慢,如果你会使用 value only test @> 运算符测试任何 json(b) 是否包含任何 json(b)。这是一个快速但您未经过测试的 NOT 选项。

简单快捷的方法:

NOT (attribute @> '"City":"Mesa"'::jsonb)

我已将 attribute->>'City' <> 'Mesa' 更改为 NOT (attribute @> '"City":"Mesa"'::jsonb),我的 ~2.000.000 行查询结果时间从 45 秒更改为 25 秒。

【讨论】:

令人沮丧的是,如果您添加了一个不错的 USING GIN(attribute) 索引,否定 @> 包含运算符会突然停止使用该索引。 NOT 不包括当你有属性但这个属性等于 NULL 的情况【参考方案3】:

您可以使用运算符<@ 这将搜索“City”不是“Mesa”的地方

select count(*) from jsonbtest WHERE attributes <@ '"City":"Mesa"';

【讨论】:

这将与select count(*) from jsonbtest WHERE '"City":"Mesa"' @&gt; attributes; 相同,检查"City": "Mesa" 是否包含不一样的attributes【参考方案4】:

这可以通过几个条件来实现。 它并不优雅,但我没有找到另一种方法。

因此,首先,获取没有“City”属性的每一行,然后添加“OR”条件以检查正确的字段值。

select count(*) from jsonbtest where 
  NOT(attributes ? 'City') 
  OR (attributes ? 'City') is NULL -- this is required if attributes can be null
  OR (attributes->>'City' != 'Mesa')) 

【讨论】:

这对我帮助很大...我在 PgSQL 站点上找不到有关此用例的任何信息。谢谢!

以上是关于Postgres jsonb“不包含”运算符的主要内容,如果未能解决你的问题,请参考以下文章

如何逃脱? (问号)运算符在 Rails 中查询 Postgresql JSONB 类型

Postgres检查jsonb数组是不是不包含值返回空结果集

如何在带有 jOOQ 的 WHERE 条件下使用 Postgres JSON 运算符?

对 PostgreSQL 中 jsonb 字段内的对象数组使用 LIKE 运算符

单个 postgresql 查询中的文本和 jsonb 连接

这两个postgres表达式会给出相同的结果吗?