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)
有一个 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)