這是一個後續問題:如何要求的Neo4j把週期考慮以優化的方式
How to ask Neo4j to take cycles into account
在我剛纔的問題,@ stdob--好心幫我找到下面的查詢:
MATCH (n1:S)
OPTIONAL MATCH (n1)-[:R]->(n2:R)<-[:R]-(n3:E)
OPTIONAL MATCH (n3t)-[:R]->(n4:R:L)
WHERE n3t = n3
RETURN labels(n1), labels(n3t), labels(n4);
上述查詢是以下替換:
MATCH (n1:S)
OPTIONAL MATCH (n1)-[:R]->(n2:R)<-[:R]-(n3:E)-[:R]->(n4:R:L)
RETURN labels(n1), labels(n3t), labels(n4);
我必須使用第一個,因爲在我的數據中可能有n2
和n4
是相同的節點,並且由於Neo4j拒絕同一個節點兩次,它將返回null。
雖然第一個查詢是有效的並且工作正常,但它的性能非常糟糕。它強制數據庫重新開始搜索整個數據,最後它將使用n3t = n3
匹配所選節點。只是爲了給您一個提示其性能有多糟糕的提示,對於200k大小的數據集,返回結果需要5秒鐘,而如果我省略第二個OPTIONAL MATCH
及其WHERE
,則結果對於相同的結果在少於10毫秒內生成查詢。如果任何人的興趣,下面是用於查詢執行計劃:
分支,在右側是我剛纔提到的部分(我試圖愚弄的Neo4j採取第二次節點)。正如你所看到的,爲了使Neo4j第二次獲得一個節點,發生了2M分貝命中。該執行計劃的實際查詢爲:
PROFILE MATCH (n5_1:Revision:`Account`)<-[:RevisionOf]-(n5_2:Entity:`Account`)
WITH n5_2, n5_1
ORDER BY n5_1.customer_number ASC
LIMIT 100
OPTIONAL MATCH (n5_1)-[:`Main Contact`]->(n4_1:Wrapper)<-[:Wrapper]-(:Revision:`Contact`)<-[:RevisionOf]-(n4_2:Entity:`Contact`)
OPTIONAL MATCH (n4_4)-[:RevisionOf]->(n4_3:Revision:Latest:`Contact`:Active)
WHERE (n4_2) = (n4_4)
RETURN n5_1, n5_2, n4_1, n4_2, n4_3
所以我的問題是,我怎麼能寫在其中一個節點採取第二次,而性能不會再遭受的Cypher查詢?
對於某些示例數據和測試牀,請轉到其他問題。
您是否考慮爲此編寫自定義過程?您可能需要查看APOC [PathExplorer]的代碼(https://github.com/neo4j-contrib/neo4j-apoc-procedures/blob/3。1/src/main/java/apoc/path/PathExplorer.java)作爲起點。這將使您更好地控制遍歷唯一性,允許您在遍歷期間重用邊緣。 – InverseFalcon
你最近的OPTIONAL MATCH有點奇怪,因爲你在這裏使用了一個新的變量'n4_4',但是在你說它必須等於'n4_2'後你有一個where子句。這種可選匹配是您擊中性能的原因。如果你在這場比賽中使用'n4_2',它應該可以工作。然而,在你的鏈接問題中,這給出了一些不希望的結果,但它看起來應該很容易過濾你必須確保'n_43'不爲空的結果。 – InverseFalcon