【问题标题】:jsonb LIKE query on nested objects in an arrayjsonb LIKE 查询数组中的嵌套对象
【发布时间】:2017-11-26 10:18:43
【问题描述】:

我的 JSON 数据如下所示:

[{
  "id": 1,
  "payload": {
    "location": "NY",
    "details": [{
            "name": "cafe",
            "cuisine": "mexican"
        },
        {
            "name": "foody",
            "cuisine": "italian"
        }
    ]
  }
}, {
  "id": 2,
  "payload": {
    "location": "NY",
    "details": [{
            "name": "mbar",
            "cuisine": "mexican"
        },
        {
            "name": "fdy",
            "cuisine": "italian"
        }
    ]
  }
}]

给定一个文本“foo”,我想返回所有包含这个子字符串的元组。但我无法弄清楚如何编写相同的查询。

我关注了this related answer,但不知道该怎么做LIKE
这就是我现在的工作:

SELECT r.res->>'name' AS feature_name, d.details::text
  FROM   restaurants r
    , LATERAL (SELECT ARRAY (
     SELECT * FROM json_populate_recordset(null::foo, r.res#>'{payload, 
       details}')
     )
   ) AS d(details)
 WHERE d.details @> '{cafe}';

我不想传递cafe 的整个文本,而是想传递ca 并获得与该文本匹配的结果。

【问题讨论】:

    标签: sql postgresql pattern-matching jsonb postgresql-9.6


    【解决方案1】:

    您的解决方案可以进一步简化:

    SELECT r.res->>'name' AS feature_name, d.name AS detail_name
    FROM   restaurants r
         , jsonb_populate_recordset(null::foo, r.res #> '{payload, details}') d
    WHERE  d.name LIKE '%oh%';
    

    或者更简单,但是,使用 jsonb_array_elements(),因为在这个示例中您实际上根本不需要行类型 (foo):

    SELECT r.res->>'name' AS feature_name, d->>'name' AS detail_name
    FROM   restaurants r
         , jsonb_array_elements(r.res #> '{payload, details}') d
    WHERE  d->>'name' LIKE '%oh%';
    

    dbfiddle here

    但这不是的完全是:

    我想返回所有包含这个子字符串的元组。

    您将返回所有 JSON 数组元素(每个基表行 0-n),其中一个特定键 ('{payload,details,*,name}') 匹配(区分大小写)。

    您最初的问题在此之上有一个嵌套的 JSON 数组。您删除了此解决方案的外部数组 - 我也这样做了。

    根据您的实际要求,new text search capability of Postgres 10 可能有用。

    【讨论】:

    • 是的,正确。但我有 id,顶级元组的名称。这就是我要返回的(具有 substr 的 id)。不过感谢您的观察。
    【解决方案2】:

    我最终这样做了(受此答案的启发 - jsonb query with nested objects in an array

    SELECT r.res->>'name' AS feature_name, d.details::text
    FROM   restaurants r
     , LATERAL  (
         SELECT * FROM json_populate_recordset(null::foo, r.res#>'{payload, details}')
       ) AS d(details)
    WHERE d.details LIKE '%oh%';
    

    在这里拉小提琴 - http://sqlfiddle.com/#!15/f2027/5

    【讨论】:

      猜你喜欢
      • 2015-05-20
      • 2019-02-17
      • 2023-04-03
      • 2017-06-27
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 2020-03-19
      相关资源
      最近更新 更多