2016-04-03 87 views
1

我正在評估ArangoDB,並發現GRAPH_EDGES和GRAPH_VERTICES命令非常緩慢,對小集合(300個頂點)。ArangoDB:GRAPH_EDGES命令對小集合非常緩慢(超過20秒)

我有3個集合:

TactiveService(300個頂點) - > TusesCommand(300個邊緣) - > Tcommand(1頂點)

使用GRAPH_EDGES,此查詢採取24秒

FOR service IN TactiveService 
    LET usesCommand = (
     return FIRST(GRAPH_EDGES("topvision", {}, { edgeExamples : [{_from: service._id}], edgeCollectionRestriction : "TusesCommand", includeData:true, maxDepth : 1 })) 
    ) 
    LET command = DOCUMENT(usesCommand[0]._to) 
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

出於同樣的結果,這個查詢需要0.020秒

FOR service IN TactiveService 
    LET usesCommand = (
     FOR usesCommand IN TusesCommand 
     FILTER usesCommand._from == service._id 
     RETURN usesCommand 
    ) 
    LET command = DOCUMENT(usesCommand[0]._to) 
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

GRAPH_EDGES是不可用的,我在發言(同樣的問題GRAPH_VERTICES)。

對這種緩慢原因的想法是受歡迎的。

回答

3

我們很清楚GRAPH_EDGES不適合在查詢中像這樣使用。

因此,我們引入了AQL pattern matching traversals,這應該會更好。

你可以制定你這樣的查詢,以遍歷替換GRAPH_EDGES

FOR service IN TactiveService 
LET usesCommand = (
        FOR v, e IN 1..1 OUTBOUND service "TusesCommand" 
         FILTER e._from == service._id RETURN e 
    ) 
    LET command = DOCUMENT(usesCommand[0]._to) 
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

請注意,指定過濾器是隱含true因爲我們查詢了OUTBOUND邊緣從service開始 - 因此e._from永遠等於service._id。我們沒有在遍歷中指定GRAPH "topvision"和稍後的限制我們想要考慮的邊緣集合,而是使用匿名圖形查詢,只考慮邊界集合TusesCommand就像您一樣。

因此簡化了一點多,查詢可能看起來像:

FOR service IN TactiveService 
LET usesCommand = (
      FOR v, e IN 1..1 OUTBOUND service "TusesCommand" RETURN {v: v, e: e} 
    ) 
RETURN { service : service, usesCommand: usesCommand} 

這可能比你的查詢返回更多的頂點,但它只是將再次獲取它們;所以結果集可能會更大,但索引查找的數量會因查詢的調用而被刪除。

正如你已經注意到和制定你的第二個查詢,如果你的實際問題更好地工作與classic join ArangoDB爲您提供自由選擇處理您的數據。

編輯:邁克爾是正確的肯定,方向必須是OUTBOUND

+0

謝謝,你的第二個查詢是完美的,並與JOIN一樣快。 –

3

如果由於某種原因,你不希望升級到2.8的@dothebart建議。您還可以修復舊的查詢。 原創:

FOR service IN TactiveService 
    LET usesCommand = (
     return FIRST(GRAPH_EDGES("topvision", {}, { edgeExamples : [{_from: service._id}], edgeCollectionRestriction : "TusesCommand", includeData:true, maxDepth : 1 })) 
    ) 
    LET command = DOCUMENT(usesCommand[0]._to) 
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

查詢的慢部分找到起點。 GRAPH_EDGES的API使用第二個參數作爲啓動示例。 {}與所有起點相符。因此它現在首先計算所有頂點的所有出邊(這是昂貴的,因爲這實際上意味着起始集合中的每個頂點,我們爲起始集合中的每個頂點收集所有邊)。比它後過濾所有找到的邊緣與你給的例子(它幾乎刪除了所有的邊緣)。 如果您將起始示例替換爲起始頂點的_id,它將僅收集此特定頂點的邊緣。 現在,您還只對一個方向(OUTBOUND)的邊緣感興趣,所以您可以在選項中給出它(因此,只有具有_from == service._id的邊緣才能由GRAPH_EDGES首先獲取)。

FOR service IN TactiveService 
    LET usesCommand = (
     RETURN FIRST(GRAPH_EDGES("topvision", service._id, { edgeCollectionRestriction : "TusesCommand", includeData:true, maxDepth : 1, direction: 'outbound' })) 
    ) 
    LET command = DOCUMENT(usesCommand[0]._to) 
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

但是我仍然認爲@dothebart的版本在2.8中更快,我也建議切換到最新版本。

+0

謝謝,使用service._id作爲開始點而不是edgeExamples更快(5秒而不是20秒)。我使用2.8。 –