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

查看:305
本文介绍了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数据库中注册该函数.
  2. 运行aql查询,该查询将构建一个平面结构(该顶点的顶点和相应路径).并将结果作为UDF函数的输入参数传递. 在这里,我的功能只是将每个元素附加到其父元素
  1. Register the function in arango db.
  2. Run your aql query, that constructs a flat structure (vertex and corresponding path for this vertex). And pass result as input parameter of your UDF function. Here my function just append each element to its parent

就我而言: 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天全站免登陆