【问题标题】:How to write jsonb inside WHERE without JSON Processing Functions如何在没有 JSON 处理函数的情况下在 WHERE 中编写 jsonb
【发布时间】:2021-08-16 22:56:20
【问题描述】:

这是我的query,它有效。我将字典列表存储在我的 jsonb 列中。

SELECT
    items.title
FROM
    items
WHERE
    jsonb_path_exists(items.types::jsonb, '$[*] ? (@.target == "discount")')

没有jsonb_path_exists()函数有没有办法写这个?

另外,JSON 处理函数是否使用索引?

我想简化查询的可读性/外观,因为它太长了。并且好奇我是否可以通过不使用 JSON 处理函数来获得任何性能改进。

我尝试用@? 替换它,但失败了。 This is what I used (quote from PostgreSQL):

jsonb@? jsonpath → 布尔值

JSON 路径是否返回指定 JSON 值的任何项目?

'{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' → t

非常感谢任何帮助。

【问题讨论】:

  • JSON 处理函数是否使用索引?” - 您引用的页面还写道“Section 8.14.4 描述了如何使用这些运算符来有效地搜索索引的 jsonb 数据” .
  • "我尝试将其替换为 @?,但失败了" - 请同时向我们展示您尝试过的查询。它是如何失败的?
  • 你为什么要把专栏投到jsonb开始?如果它被定义为jsonb,则强制转换是无用的(您可以通过删除它来缩短查询)。如果它是json(或者更糟糕的text),那么您应该将其转换为jsonb,这样您就不需要在任何地方进行强制转换,并且索引更容易定义(和使用)

标签: postgresql postgresql-13 postgresql-json


【解决方案1】:

jsonb_path_xxx() 函数和等效运算符之间的 JSON 路径评估略有不同。最重要的是,您不需要 ? (...) 条件,因为这是在使用运算符时隐含的。

以下应该是等价的:

where items.types::jsonb @? '$[*].target == "discount"'

如果您想简化或缩短查询,请为items 引入别名,这样您就无需在任何地方重复完整的表名。将列 types 转换为 jsonb 将进一步简化您的查询,因为您不再需要强制转换。


很好奇我是否可以通过不使用 JSON 处理函数来获得任何性能改进。

@? 运算符可以使用 of a GIN index - 但这仅适用于 jsonb,不适用于 json 数据类型。

上面的where条件可以使用下面的索引:

create index on items using gin ( (types::jsonb) );

如果列被正确定义为jsonb,则可以通过删除强制转换来简化索引定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 2022-06-10
    • 1970-01-01
    • 2021-05-21
    相关资源
    最近更新 更多