简而言之,是否有一种方法可以从Postgres的jsonb对象中获取jsonb_array类型的值?
尝试使用Postgres中的递归CTE将任意深度的树形结构展平,例如:
{
"type": "foo",
"properties": {...},
"children": [
"type": "bar",
"properties": {...},
"children": [
"type": "multivariate",
"variants": {
"arbitrary-name": {
properties: {...},
children: [...],
},
"some-other-name": {
properties: {...},
children: [...],
},
"another": {
properties: {...},
children: [...],
}
}
]
]
}
通常遵循这篇文章,但我在处理
type: "multivariate"
节点时卡住了,我真正想要的是jsonb_agg(jsonb_object_values(json_object -> 'variants'))
。
更新:
抱歉,我显然应该包括我尝试过的查询:
WITH RECURSIVE tree_nodes (id, json_element) AS (
-- non recursive term
SELECT
id, node
FROM trees
UNION
-- recursive term
SELECT
id,
CASE
WHEN jsonb_typeof(json_element) = 'array'
THEN jsonb_array_elements(json_element)
WHEN jsonb_exists(json_element, 'children')
THEN jsonb_array_elements(json_element -> 'children')
WHEN jsonb_exists(json_element, 'variants')
THEN (select jsonb_agg(element.value) from jsonb_each(json_element -> 'variants') as element)
END AS json_element
FROM
tree_nodes
WHERE
jsonb_typeof(json_element) = 'array' OR jsonb_typeof(json_element) = 'object'
)
select * from tree_nodes;
这个模式只是一个id
和一个jsonb node
列
这个查询会报错:
ERROR: set-returning functions are not allowed in CASE
LINE 16: THEN jsonb_array_elements(json_element -> 'children')
^
HINT: You might be able to move the set-returning function into a LATERAL FROM item.
我只想要Object.values(json_element -> 'variants')
更新2:
再次阅读后,我意识到这是一个问题,因为我使用的是最新版本的PostgreSQL(10.3),它显然不再允许从CASE
语句返回一个集合,而这似乎是实现树形展开方法的关键。在最新版本的PostgreSQL中可能有一些达成相同目的的方法,但我不知道如何去做。
变量
引起的,而是children
数组。我列出的文章中的示例在 Postgres 10 中根本不可能实现吗? - stevesetof jsonb
函数的CASE
语句更清晰、更易于维护,这是我个人的看法。 - Timshel