Postgres:查询多个jsonb字段

Postgres: Querying multiple jsonb fields

有一个 table 和一个包含 jsonb 数据的列,我想查询那些具有多个字段的数据。 jsonb 结构如下所示:

{
  "https://example.tld/": 
  [
    {
      "content-length": 312,
      "path": "page.log",
      "redirect": null,
      "status": 200
    },
    {
      "content-length": 312,
      "path": "pages/",
      "redirect": null,
      "status": 200
    },
    ...
  ]
}

我想查询状态为 200 的所有日志文件,所以我做了

SELECT json_data -> 'path' AS path
FROM table
WHERE json_data->'status' = 200 AND json_data->'path' ILIKE '%.log%'

但是,它不起作用。我开始工作的最接近的变体是,如果我将 json 内容转换为文本并搜索日志,但它 returns 整个内容。

SELECT *
FROM table
WHERE json_data::text ILIKE '%.log%'

感谢您的帮助!

如果我没理解错的话,您需要 JSON 中底层数组的路径。如果是:

select rs.path
from t cross join
     jsonb_to_recordset(t.json -> 'https://example.tld/') rs(status int, path text)
 where rs.path ilike '%.log%' and rs.status = 200

Here 是一个 db<>fiddle.

假设 top-level 键名(在本例中为 https://example.tld/)在您的 table 中逐行更改,您将无法使用固定路径,并且在使用 jsonb_array_elements().

扩展数组元素之前使用 jsonb_each() 扩展对象
with indat as ( select 1 as id, '{
  "https://example.tld/":
  [
    {
      "content-length": 312,
      "path": "page.log",
      "redirect": null,
      "status": 200
    },
    {
      "content-length": 312,
      "path": "pages/",
      "redirect": null,
      "status": 200
    }
  ]
}'::jsonb as json_data
)
select i.id, j.key, e.element
  from indat i
 cross join lateral jsonb_each(json_data) as j(key, value)
 cross join lateral jsonb_array_elements(j.value) as e (element)
 where e->>'path' ilike '%.log%'
   and e->>'status' = '200';

 id |         key          |                                   element
----+----------------------+------------------------------------------------------------------------------
  1 | https://example.tld/ | {"path": "page.log", "status": 200, "redirect": null, "content-length": 312}
(1 row)