簡體   English   中英

在ArangoDB中的大型二部圖上使用AQL進行有效的路徑遍歷

[英]Efficient path traversal using AQL on a large bipartite graph in ArangoDB

我有一個使用兩個集合和一個邊緣列表存儲在ArangoDB中的大型二部圖(300M +節點)。 我正在嘗試使用AQL進行有效遍歷,該AQL從具有特定標簽的一種類型的節點開始,以查找具有相同標簽的相同類型的所有其他連接節點。 遍歷的結果可能會發現2到15萬個節點之間的任何地方,盡管平均而言大約是10到20個節點。 重要的是,a)我指定一個較大的默認最大遍歷深度(即0..50)以確保找到所有內容,但是b)AQL修剪路徑,以便在大多數情況下它永遠不會達到該最大深度。

我有一個查詢,可以得到正確的結果,但是它似乎沒有修剪路徑,因為即使增加了最大深度,它也會變慢,即使結果沒有變化。

這是縮影的問題( 圖片在這里 ):

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, {});

從Node 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] )。

據我所知,優化器目前只有一種模式可以識別修剪路徑而不是后過濾,這是結合ALL運算符對路徑變量進行的簡單過濾。

您添加的嵌入式過濾器可能會阻止應用此優化。 我不明白您為什么首先添加它。 沒有color屬性的頂點的隱含值null ,它不等於'blue' ,因此是不必要的。

該查詢是否產生相同的結果,但是隨着遍歷深度的增加而更快?

FOR v, e, p IN 0..5 ANY "circles/A" owns 
    FILTER p.vertices[*].color ALL == 'blue'
    return v._id

有一個開放功能請求要求提供一種明確的修剪路徑的方法。 隨時添加您的用例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM