查询嵌套 JSON 数组 PostgreSQL 中的所有元素
Posted
技术标签:
【中文标题】查询嵌套 JSON 数组 PostgreSQL 中的所有元素【英文标题】:Query All Elements in Nested JSON Array PostrgreSQL 【发布时间】:2020-12-10 03:07:26 【问题描述】:我正在尝试在 SQL 中创建一个查询来检索 DNS 答案信息,以便我可以通过添加 TimescaleDB 在 Grafana 中将其可视化。现在,我正在努力让 postgres 一次查询多个元素。我尝试查询的 JSON 的结构如下所示:
"Z": 0,
"AA": 0,
"ID": 56559,
"QR": 1,
"RA": 1,
"RD": 1,
"TC": 0,
"RCode": 0,
"OpCode": 0,
"answer": [
"ttl": 19046,
"name": "i.stack.imgur.com",
"type": 5,
"class": 1,
"rdata": "i.stack.imgur.com.cdn.cloudflare.net"
,
"ttl": 220,
"name": "i.stack.imgur.com.cdn.cloudflare.net",
"type": 1,
"class": 1,
"rdata": "104.16.30.34"
,
"ttl": 220,
"name": "i.stack.imgur.com.cdn.cloudflare.net",
"type": 1,
"class": 1,
"rdata": "104.16.31.34"
,
"ttl": 220,
"name": "i.stack.imgur.com.cdn.cloudflare.net",
"type": 1,
"class": 1,
"rdata": "104.16.0.35"
],
"ANCount": 13,
"ARCount": 0,
"QDCount": 1,
"question": [
"name": "i.stack.imgur.com",
"qtype": 1,
"qclass": 1
]
可以有任意数量的答案,包括零,所以我想找出一种方法来查询所有答案。例如,我正在尝试从每个索引答案中检索 ttl 字段,并且我可以查询特定索引,但无法查询所有匹配项。
这适用于查询单个索引:
SELECT (data->'answer'->>0)::json->'ttl'
FROM dns;
当我环顾四周时,我发现这是查询数组中所有索引的潜在解决方案,但它似乎不起作用并告诉我“无法从标量中提取元素”:
SELECT answer->>'ttl' ttl
FROM dns, jsonb_array_elements(data->'answer') answer, jsonb_array_elements(answer->'ttl') ttl
【问题讨论】:
【参考方案1】:使用jsonb_array_elements()
将为answer
数组中的每个对象提供一行。然后您可以取消引用该对象:
select a.obj->>'ttl' as ttl, a.obj->>'name' as name, a.obj->>'rdata' as rdata
from dns d
cross join lateral jsonb_array_elements(data->'answer') as a(obj)
【讨论】:
非常感谢!这行得通。你有什么资源可以推荐来学习交叉连接吗?恐怕我对他们不熟悉。 是的。请看Lateral Subqueries
:postgresql.org/docs/current/queries-table-expressions.htmlcross
表示没有连接条件,其中包括一个表中的每一行的一个副本与另一个表中的每一行配对,又名“笛卡尔积”。 lateral
是魔法。这将连接的“表”与查询的当前行相关联。在这种情况下,data
在运行时是可访问的,jsonb_array_elements()
的结果被视为表格。如果dns
中有另一列,请将其添加到select
列表中以更好地说明。以上是关于查询嵌套 JSON 数组 PostgreSQL 中的所有元素的主要内容,如果未能解决你的问题,请参考以下文章
将新的键/值对添加到 PostgreSQL JSON 列内的嵌套数组中
如何在 PostgreSQL JSONB 列中查询具有异构元素的嵌套数组
plpgsql jsonb_set 用于带有嵌套数组的 JSON 对象数组