ArangoDB通过节点属性高效遍历
ArangoDB efficient traversal via node attributes
在 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" 边缘并收集属于
种类=项目和名称=项目1
- 遍历子边并收集属于
kind=library and name=library1
这可以在嵌套的 select 语句中完成。 kind 字段被索引,因此可以从大量对象中快速收集起始节点。为了进一步提高性能,我知道 tables(集合)中有哪些种类,因此我可以将对象的数量范围限定为 select from (select from
其中 kind=site).
在ArrangoDB中,只有边有节点绑定信息,所以有一个节点我不能直接穿过连接的边。在 GRAPH_TRAVERSAL 函数中,我可以通过示例指定起始集合。所以这个例子是{kind=site}。这是否意味着必须通过扫描所有图边来收集节点的起始列表,基本上是查看连接到整个图中每条边输入的每个节点?
如何制定这样的查询(在 AQL and/or arangojs 中)以便它不必从对连接到边缘的对象进行全面扫描开始?
我也不知道如何将示例顶点发送到 arangojs 遍历函数中。它似乎总是想要一个明确的起始顶点。
考虑到这样的工作,我们设计了新的 AQL graph traversal,它将与 ArangoDB 2.8(目前处于后期测试阶段)一起发布
关于你的最后一点,我们使用 named graphs 识别相关集合,它知道集合及其在图中的关系。因此,我假设您将使用 named graphs
。
让我们将 one of the ArangoDB 2.8 Example graphs 与 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 graph traversal chapter也有深入的解释,遍历器以何种方式遍历图形。
在 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" 边缘并收集属于 种类=项目和名称=项目1
- 遍历子边并收集属于 kind=library and name=library1
这可以在嵌套的 select 语句中完成。 kind 字段被索引,因此可以从大量对象中快速收集起始节点。为了进一步提高性能,我知道 tables(集合)中有哪些种类,因此我可以将对象的数量范围限定为 select from (select from