【问题标题】:jsonb find a value in an arrayjsonb 在数组中找到一个值
【发布时间】:2021-07-05 03:23:42
【问题描述】:

有这样一个数据结构:

Column "recipient" type jsonb

{
  "phoneNumbers": [
    {
      "isDefault": true,
      "type": "MOBILE",
      "number": "3454654645"
    },
    {
      "isDefault": true,
      "type": "MOBILE",
      "number": "12423543645"
    }
  ]
}

我需要按数字编写搜索请求。在 postgres 文档中,我没有在数组中找到按值搜索,只有通过索引获得。不适合我

我做了一个这样的查询,它被执行了,但是还有其他方法可以搜索数组吗?

SELECT * 
FROM my_table
WHERE recipient -> 'phoneNumbers' @> '[{"number":3454654645}]'

【问题讨论】:

    标签: sql arrays json postgresql jsonb


    【解决方案1】:

    这几乎是最好的方法,是的。

    如果您在 recipient 上有一个 (GIST) 索引,则您的条件不会使用该索引。但以下可以使用这样的索引:

    SELECT * 
    FROM my_table
    WHERE recipient @> '["phoneNumbers": {"number":3454654645}]}'
    

    如果您使用的是 Postgres 12 或更高版本,您还可以使用 JSON 路径表达式:

    SELECT * 
    FROM my_table
    WHERE recipient @@ '$.phoneNumbers[*].number == "12423543645"'
    

    如果您无法将 JSON 对象传递给查询,则可以使用 EXISTS 子选择:

    SELECT mt.*
    FROM my_table mt
    WHERE EXISTS (SELECT * 
                  FROM jsonb_array_elements_text(mt.recipient -> 'phoneNumbers') as x(element)
                  WHERE x.element ->> 'number' = '3454654645')
    

    '3454654645' 可以作为参数传递给您的查询。不过,这永远不会使用索引。

    【讨论】:

    • 但是有可能以某种方式遍历数组吗?
    • 我不确定你到底想通过“迭代”来实现什么。这两个条件都将检查所有数组元素(因此它们隐含地“迭代”)
    • @a_horse_with_no_name 问题是我动态地进行替换而不是“12423543645”。是否可以不带引号进行查询,因为 postgres 将其解释为字符串并且不允许动态替换值。
    • @hulxfp:但是您在示例 JSON 中的值也被引用,这就是为什么您也需要在搜索条件中引用它们。但是如果您不能将“JSON 值”传递给您的查询,您可以使用子查询
    猜你喜欢
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 2015-09-10
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多