Arangodb AQL 递归图遍历 [英] Arangodb AQL recursive graph traversal

查看:28
本文介绍了Arangodb AQL 递归图遍历的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含三个集合的图,这些集合可以通过边连接.ItemA 是 itemB 的父项,而后者又是 itemC 的父项.元素只能由方向上的边连接

I have a graph with three collections which items can be connected by edges. ItemA is a parent of itemB which in turn is a parent of itemC. Elements only can be connected by edges in direction

"_from : child, _to : parent"

目前我只能通过这个 AQL 查询获得线性"结果:

Currently I can get only "linear" result with this AQL query:

LET contains = (FOR v IN 1..? INBOUND 'collectionA/itemA' GRAPH 'myGraph' RETURN v)

     RETURN {
        "root": {
            "id": "ItemA",
            "contains": contains
       }
   }

结果如下:

"root": {
    "id": "itemA",
    "contains": [
        {
            "id": "itemB"
        },
        {
            "id": "itemC"
        }
    ]
}

但我需要像这样获得图遍历的分层"结果:

But I need to get a "hierarchical" result of graph traversal like that:

"root": {
    "id": "itemA",
    "contains": [
        {
            "id": "itemB",
            "contains": [
                {
                    "id": "itemC"
                }
            }
        ]
    }

那么,我可以在运行 aql 查询时获得这个分层"结果吗?

So, can I get this "hierarchical" result running an aql query?

还有一件事:遍历应该运行直到遇到叶节点.所以遍历的深度是事先未知的.

One more thing: traversal should run until leaf nodes will be encountered. So depth of the traversal is unknown in advance.

推荐答案

我找到了解决方案.我们决定使用 UDF (用户定义函数).

I have found solution. We decided to use UDF (user defined functions).

以下是构建适当层次结构的几个步骤:

Here is a few steps to construct the proper hierarchical structure:

  1. 在 arango db 中注册函数.
  2. 运行您的 aql 查询,它构建一个平面结构(顶点和该顶点的相应路径).并将结果作为 UDF 函数的输入参数传递.这里我的函数只是将每个元素附加到其父元素

就我而言:1) 在arango db中注册函数.

In my case: 1) Register the function in arango db.

db.createFunction(
        'GO::LOCATED_IN::APPENT_CHILD_STRUCTURE',
            String(function (root, flatStructure) {
                if (root && root.id) {
                    var elsById = {};
                    elsById[root.id] = root;

                    flatStructure.forEach(function (element) {
                        elsById[element.id] = element;
                        var parentElId = element.path[element.path.length - 2];
                        var parentEl = elsById[parentElId];

                        if (!parentEl.contains)
                            parentEl.contains = new Array();

                        parentEl.contains.push(element);
                        delete element.path;
                    });
                }
                return root;
            })
        );

2) 使用 udf 运行 AQL:

2) Run AQL with udf:

    LET flatStructure = (FOR v,e,p IN 1..? INBOUND 'collectionA/itemA' GRAPH 'myGraph' 
       LET childPath = (FOR pv IN p.vertices RETURN pv.id_source)
    RETURN MERGE(v, childPath))

    LET root = {"id": "ItemA"} 

    RETURN GO::LOCATED_IN::APPENT_CHILD_STRUCTURE(root, flatStructure)

注意:请不要忘记 命名约定.

这篇关于Arangodb AQL 递归图遍历的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆