通过节点属性实现高效的ArangoDB遍历

3
在OrientDB中,每个顶点都有连接的边缘。这意味着可以使用嵌套的“select”语句显式地从集合中遍历节点。例如:给定节点属性路径,查找匹配的终端节点。该路径由一系列节点属性组成(例如,在路径中节点中唯一的“kind”)。现在,假设我有一棵树:
kind=site, name=site1
  -- kind=project, name=project1
  -- kind=library, name=library1
kind=site, name=site2
  -- kind=project, name=project2
  -- kind=library, name=library1

用户想要从路径为library1的库中获取信息:

[{kind=site},{kind=project,name=project1},{kind=library,name=library1}]

如果结果是单个节点,则不必为遍历每个节点进行全面限定。在OrientDB中,该过程将如下所示:
- 从kind=site的所有节点开始 - 遍历“child”边缘并收集所有kind=project且name=project1的对象 - 遍历子边缘并收集所有kind=library且name=library1的对象
可以在嵌套的select语句中完成此操作。kind字段已索引,因此可以快速从大量对象中收集起始节点。为了进一步提高性能,我知道哪些种类在哪个表(集合)中,因此可以将要选择的对象数量范围限定到(select from where kind=site)。


在ArrangoDB中,只有边缘具有节点绑定信息,因此如果没有节点,我无法直接遍历连接的边缘。在GRAPH_TRAVERSAL函数中,我可以通过示例指定起始集合。所以示例将是{kind=site}。这是否意味着必须通过扫描整个图形边缘来获取起始节点列表,基本上查看与整个图形边缘输入相连的每个节点?如何构建此类查询(在AQL和/或arangojs中),以便不必从与边缘连接的对象进行完全扫描?我还不知道如何将示例顶点发送到arangojs遍历函数中。它似乎总是需要一个明确的起始顶点。
1个回答

1

考虑到这样的工作,我们设计了新的AQL图遍历,将在ArangoDB 2.8(目前处于后期测试阶段)发布。

关于您最后的问题,我们使用命名图来识别相关集合,这些图知道图中集合及其关系。我假设您将使用命名图

让我们使用ArangoDB 2.8示例图之一和arangosh:

var examples = require("org/arangodb/graph-examples/example-graph.js");
var graph = examples.loadGraph("traversalGraph");

它在“circles”集合中有其顶点,在“edges”集合中连接顶点的边缘:
db.circles.toArray();
db.edges.toArray();

现在我们可以使用与遍历深度结合的FILTER语句来提前修剪图分支的遍历执行。
在这里,我们过滤出一个顶点的属性在遍历的第一层中被发现:
db._query("FOR v, e, p IN 1..3 " + 
              "OUTBOUND 'circles/A' " + 
              "GRAPH 'traversalGraph' " + 
              "FILTER p.vertices[1]._key != 'G' RETURN v._key");

我们也可以以类似的方式过滤边缘的属性:
db._query("FOR v, e, p IN 1..3 "
          "OUTBOUND 'circles/A' " +
          "GRAPH 'traversalGraph' " + 
          "FILTER p.edges[0].label != 'right_foo' RETURN v._key");

AQL图遍历章节也有深入的解释,说明了遍历器如何在图上移动。


这正是我一直在寻找的。我将注释我的代码中那些可以从这个功能中受益的查询位置。我们仍处于可行性阶段,所以我还有一点时间。 - ggendel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接