Postgres:查询多个jsonb字段

Posted

技术标签:

【中文标题】Postgres:查询多个jsonb字段【英文标题】:Postgres: Querying multiple jsonb fields 【发布时间】:2020-08-14 11:36:13 【问题描述】:

有一个包含 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 内容转换为文本并搜索日志,但它会返回整个内容。

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

感谢您的帮助!

【问题讨论】:

您使用的是哪个 Postgres 版本? (PostgreSQL) 10.12 【参考方案1】:

如果我理解正确,您需要 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 是一个 dbfiddle。

【讨论】:

非常感谢!如何使查询独立于特定域?有没有像 t.json->[0] 这样的可能?我的意思是查询第一个数组条目而不指定example.tld之类的域名。 @a_horse_with_no_name 我得到“错误:无法在非数组上调用 jsonb_to_recordset” @nullpointr 。 . . (1) 我建议你问一个新问题。 (2) 最简单的方法是将域包含在数组中,而不是让它成为一个key【参考方案2】:

假设***键名(在这种情况下为https://example.tld/)在您的表中逐行更改,您将无法使用固定路径,并且必须在扩展之前使用jsonb_each() 扩展对象带有jsonb_array_elements() 的数组元素。

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)


【讨论】:

以上是关于Postgres:查询多个jsonb字段的主要内容,如果未能解决你的问题,请参考以下文章

Postgres jsonb null vs 空对象查询性能

如何根据postgres的jsonb列的where条件(无本机查询)使用jpa在spring boot中选择数据?

Postgres 检查空 JSONB 字段

从 Postgres 中的 JSONB 字段中选择不为空的值

jsonb字段上的Spring-Data-JPA本机查询

结合关系查询提高 Postgres jsonb 查询的性能