jsonb LIKE查询数组中的嵌套对象

时间:2017-06-23 00:17:28

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

我的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并获得与该文字匹配的结果。

2 个答案:

答案 0 :(得分:0)

我最终做到了这一点(灵感来自这个答案 - 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

答案 1 :(得分:0)

您的解决方案可以更简化:

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可能会有用。