我有一个使用两个集合和一个边缘列表存储在ArangoDB中的大型二部图(300M +节点)。我正在尝试使用AQL进行有效遍历,该AQL从具有特定标签的一种类型的节点开始,以查找具有相同标签的相同类型的所有其他连接节点。遍历的结果可能会发现2到15万个节点之间的任何地方,尽管平均而言大约是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]
)。
答案 0 :(得分:0)
据我所知,优化器当前仅能识别一种修剪模式而不是后过滤的模式,这是结合ALL
运算符的路径变量上的普通过滤器
您添加的嵌入式过滤器可能会阻止应用此优化。我不明白您为什么首先添加它。没有color
属性的顶点具有null
的隐式值,该值不等于'blue'
,因此是不必要的。
此查询是否产生相同的结果,但是随着遍历深度的增加而更快?
FOR v, e, p IN 0..5 ANY "circles/A" owns
FILTER p.vertices[*].color ALL == 'blue'
return v._id
有一个open feature request用于修剪路径的显式方法。随时添加您的用例。