栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Postgres-将邻接表转换为嵌套的JSON对象

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Postgres-将邻接表转换为嵌套的JSON对象

使用

WITH RECURSIVE
(https://www.postgresql.org/docs/current/static/queries-
with.html
)和JSON函数(https://www.postgresql.org/docs/current/static/functions-
json.html
)我建立这个解决方案:

db
<>小提琴

核心功能:

    WITH RECURSIVE tree(node_id, ancestor, child, path, json) AS  (      SELECtt1.node_id,NULL::int,t2.node_id,          '{children}'::text[] ||   (row_number() OVER (PARTITION BY t1.node_id ORDER BY t2.node_id) - 1)::text,-- C          jsonb_build_object('name', t2.name, 'children', array_to_json(ARRAY[]::int[])) -- B      FROM test t1      LEFT JOIN test t2 ON t1.node_id = t2.parent_node  -- A      WHERe t1.parent_node IS NULL      UNIOn      SELECt          t1.node_id,t1.parent_node,t2.node_id,          tree.path || '{children}' || (row_number() OVER (PARTITION BY t1.node_id ORDER BY t2.node_id) - 1)::text,jsonb_build_object('name', t2.name, 'children', array_to_json(ARRAY[]::int[]))      FROM test t1      LEFT JOIN test t2 ON t1.node_id = t2.parent_node      INNER JOIN tree ON (t1.node_id = tree.child)      WHERe t1.parent_node = tree.node_id    -- D    )    SELECt  -- E        child as node_id, path, json     FROM tree     WHERe child IS NOT NULL ORDER BY path

每个元素都

WITH RECURSIVE
包含一个开始
SELECt
部分和一个递归部分(第二个部分
SELECT
),并由组合
UNIOn

答:再次参加餐桌本身就可以找到的孩子

node_id

B:为孩子建立json对象,可以将其插入其父对象

C:构建必须在其中插入子对象的路径(从根目录开始)。窗口函数

row_number()
(https://www.postgresql.org/docs/current/static/tutorial-
window.html)生成父级子级数组中子级的索引。

D:递归部分作为初始部分起作用,但有一个区别:它不是在搜索根元素,而是在搜索具有上一个递归的父节点的元素。

E:执行递归并过滤所有元素而没有任何子元素将得到以下结果:

node_id   pathjson2         children,0     {"name": "node2", "children": []}4         children,0,children,0     {"name": "node4", "children": []}5         children,0,children,1     {"name": "node5", "children": []}6         children,0,children,2     {"name": "node6", "children": []}3         children,1     {"name": "node3", "children": []}7         children,1,children,0     {"name": "node7", "children": []}8         children,1,children,1     {"name": "node8", "children": []}

尽管我找不到在递归中添加所有子元素的方法(origin
json不是全局变量;所以它始终知道直接祖先的更改,而不是其兄弟姐妹的更改),但我不得不在几秒钟的时间内迭代这些行。

这就是为什么我构建函数。在这里,我可以对全局变量进行迭代。使用该功能,

jsonb_insert
我将所有计算出的元素插入到根json对象中-
使用计算出的路径。

CREATE OR REPLACE FUNCTION json_tree() RETURNS jsonb AS $$DECLARE    _json_output jsonb;    _temprow record;BEGIN    SELECT         jsonb_build_object('name', name, 'children', array_to_json(ARRAY[]::int[]))     INTO _json_output     FROM test     WHERe parent_node IS NULL;    FOR _temprow IN            LOOP        SELECT jsonb_insert(_json_output, _temprow.path, _temprow.json) INTO _json_output;    END LOOP;    RETURN _json_output;END;$$ LANGUAGE plpgsql;

最后一步是调用函数,并使JSON更具可读性(

jsonb_pretty()

{    "name": "node1",    "children": [{        "name": "node2",        "children": [{ "name": "node4", "children": []        },        { "name": "node5", "children": []        },        { "name": "node6", "children": []        }]    },    {        "name": "node3",        "children": [{ "name": "node7", "children": []        },        { "name": "node8", "children": []        }]    }]}

我敢肯定有可能优化查询,但是对于草图它是可行的。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/387605.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号