[英]AQL to validate path to node
我們需要具有一些AQL,以驗證到實體的特定路徑。 由於需要掃描整個集合,因此當前解決方案的性能非常差。
例如,在這里,我們有3個實體“類型”:a,b,c(盡管它們都在單個集合中)以及它們之間的特定邊緣集合,我們想要確定_key“ 123”和_key之間是否存在連接正好通過a-> b-> c的“ 234”。
FOR a IN entities FILTER e._key == "123" FOR b IN 1..1 OUTBOUND e edges_a_to_b FOR c IN 1..1 INBOUND e_1 edges_c_to_b FILTER e_2._key == "234" ...
這可以很快散開!
我們還有另一種解決方案,其中我們使用最短路徑並指定適當的方向和邊緣集合,這要快得多(> 100倍)。 但是擔心這種方法不能完全滿足我們的一般情況……邊緣的順序沒有得到執行,並且我們可能必須多次通過同一個邊緣集合,而這是我們無法使用的語法。
還有另一種方法,可能涉及遍歷中的路徑嗎?
謝謝! 擔。
如果我正確理解,您將始終知道兩個頂點之間所需的確切路徑。
因此,以path.vertices == [a, b, c]
a -> b -> c
為例,有效的結果將是: path.vertices == [a, b, c]
因此,我們可以使用此路徑對其進行過濾,僅當您使用單個路徑時才有效遍歷步驟,而不是多個。 因此,我們嘗試使用的是以下模式:
FOR c,e, path IN <pathlength> <direction> <start> <edge-collections>
FILTER path.vertices[0] == a // This needs to be formulated correctly
FILTER path.vertices[1] == b // This needs to be formulated correctly
FILTER path.vertices[2] == c // This needs to be formulated correctly
LIMIT 1 // We only net exactly one path, so limit 1 is enough
[...]
因此,有了這個提示,就可以通過以下方式編寫查詢:
FOR a IN entities
FILTER a._key == "123"
FOR c, e, path IN 2 OUTBOUND a edges_a_to_b, INBOUND edges_b_to_c
FILTER path.vertices[1] == /* whatever identifies b e.g. vertices[1].type == "b" */
FILTER path.vertices[2]._key == "234"
LIMIT 1 /* This will stop as soon as the first match is found, so very important! */
/* [...] */
這將使優化程序可以盡早應用過濾條件,並且(幾乎)將使用與最短路徑實現相同的算法。 訣竅是使用一次遍歷而不是多次遍歷以節省內部開銷並允許更好的優化。
還請注意,朝相反的方向搜索可能會更好:
例如,代替a- a -> b -> c
檢查c <- b <- a
-a可能更快。 這取決於每個節點的邊緣數量。 我假設醫生有很多手術,但是一個病人很可能只有少量手術,因此最好是從病人那里開始並向后檢查,而不是從醫生那里開始並向前檢查。
請讓我知道它已經對您有所幫助,否則我們可以討論更多詳細信息,並查看是否可以找到進一步的優化方法。
免責聲明:我是ArangoDB的Core-Dev團隊的成員
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.