【发布时间】:2018-07-30 00:10:45
【问题描述】:
我有一个使用两个集合和一个边列表存储在 ArangoDB 中的大型二分图(300M+ 个节点)。我正在尝试使用 AQL 进行有效的遍历,该遍历从具有特定标签的一种类型的节点开始,以查找具有相同标签的相同类型的所有其他连接节点。由此产生的遍历可以找到 2 到 150K 节点之间的任何位置,但平均而言它将是大约 10-20 个节点。重要的是 a) 我指定了一个较大的默认最大遍历深度(即 0..50)以确保我找到所有内容,但是 b) AQL 修剪路径以便大多数时候它永远不会达到这个最大深度。
我有一个得到正确结果的查询,但它似乎没有修剪路径,因为随着我增加最大深度它会变慢,即使结果没有改变。
这是问题的缩影 (picture here):
var cir = db._create("circles");
var dia = db._create("diamonds");
var owns = db._createEdgeCollection("owns");
var A = cir.save({_key: "A", color:'blue'});
var B = cir.save({_key: "B", color:'blue'});
var C = cir.save({_key: "C", color:'blue'});
var D = cir.save({_key: "D", color:'yellow'});
var E = cir.save({_key: "E", color:'yellow'});
var F = cir.save({_key: "F", color:'yellow'});
var G = cir.save({_key: "G", color:'red'});
var H = cir.save({_key: "H", color:'red'});
var d1 = dia.save({_key: "1"})_id;
var d2 = dia.save({_key: "2"})_id;
var d3 = dia.save({_key: "3"})_id;
var d4 = dia.save({_key: "4"})_id;
var d5 = dia.save({_key: "5"})_id;
var d6 = dia.save({_key: "6"})_id;
owns.save(A, d2, {});
owns.save(A, d5, {});
owns.save(A, d4, {});
owns.save(B, d4, {});
owns.save(C, d5, {});
owns.save(C, d6, {});
owns.save(D, d1, {});
owns.save(D, d2, {});
owns.save(E, d1, {});
owns.save(E, d3, {});
owns.save(F, d3, {});
owns.save(F, d4, {});
owns.save(G, d6, {});
owns.save(H, d6, {});
owns.save(H, d2, {});
从节点circle/A 开始,我想找到所有连接的顶点,只有在遇到不是blue 的圆时才会停止。
以下 AQL 可以满足我的要求:
FOR v, e, p IN 0..5 ANY "circles/A" owns
FILTER p.vertices[* filter has(CURRENT, 'color')].color ALL == 'blue'
return v._id
但 FILTER 子句不会导致任何修剪发生。至少,正如我上面所说,在我拥有的大型数据库中,增加最大深度会使其非常慢,而不会改变结果。
那么我如何确保路径的过滤导致算法修剪路径?文档对此有点薄。我只能找到使用精确路径长度的示例(例如p.vertices[1])。
【问题讨论】: