2015-04-30 43 views
3

我正在使用neo4j圖形數據庫版本2.1.7。關於數據的簡要細節: 具有6種不同類型的節點的200萬個節點,僅具有5種不同類型的關係的500萬個關係以及大多數連接的圖,但包含一些孤立的子圖。在neo4j圖表中刪除路徑的更好方法

解析路徑時,我得到路徑中的循環。而對於限制,我用下面的共享解決方案: Returning only simple paths in Neo4j Cypher query

下面是該查詢,我使用:

MATCH (n:nodeA{key:905728}) 
MATCH path = n-[:rel1|rel2|rel3|rel4*0..]->(c:nodeA)-[:rel5*0..1]->(b:nodeA) 
WHERE ALL(a in nodes(path) where 1=length (filter (m in nodes(path) where m=a))) 
and (length(EXTRACT (p in NODES(path)| p.key)) > 1) 
and ((exists ((c)-[:rel5]->(b)) and (not exists((b)-[:rel1|rel2|rel3|rel4]->(:nodeA)) OR ANY (x in nodes(path) where (b)-[]->(x)))) 
    OR (not exists ((c)-[:rel5]->()) and (not exists ((c)-[:rel1|rel2|rel3|rel4]->(:nodeA)) OR ANY (x in nodes(path) where (c)-[]->(x))))) 
RETURN distinct EXTRACT (rp in Rels(path)| type(rp)), EXTRACT (p in NODES(path)| p.key); 

上面的查詢解決了我的要求,但並不符合成本效益,並保持運行,如果被運行的巨大子圖。我使用'Profile'命令來提高查詢性能。但是,現在停留在這一點上。性能有所提高,但不是我所期望的neo4j :(

回答

1

我不知道我有一個解決方案,但我有一些建議。有些可能會加快速度,有些可能會讓查詢更容易。閱讀

首先,而不是把exists ((c)-[:rel5]->(b))WHERE,我相信你可以把它放在你的MATCH這樣的:

MATCH path = n-[:rel1|rel2|rel3|rel4*0..]->(c:nodeA)-[:rel5*0..1]->(b:nodeA), (c)-[:rel5]->(b) 

我不認爲你需要的exists關鍵字我想你可以說,例如,(NOT (b)-[:rel1|rel2|rel3|rel4]->(:nodeA))

我還建議您考慮WITH clause以獲得潛在的性能改進。

有關您的可變路徑的一些注意事項:*0..0意味着您可能尋找自我引用。這可能是也可能不是你想要的。另外,將可變路徑保持開放狀態通常會導致性能問題(正如我認爲您所看到的那樣)。如果你有可能限制它可能會有所幫助。另外,如果升級到2.2.1,則2.2.x版本中會有一些內置的性能改進,但是您還可以在控制檯中獲得視覺PROFILE,並且可以使用新的EXPLAIN命令,其中包括配置文件和在運行後告訴你查詢的真實性能。

還有一點需要考慮的是,我認爲你並沒有達到Neo4j的性能邊界,而是或許你有可能觸及Cypher的某些邊界。如果是這樣,我可能會建議您使用Neo4j提供的Java API進行查詢,以獲得更好的性能和更多的控制權。這可以通過嵌入數據庫,如果你使用的是JVM兼容語言,或者通過編寫一個unmanaged extension,它可以讓你自己查詢java,但是從服務器提供一個定製的REST API

+0

感謝@Brian的迴應。我肯定會處理您分享的建議並分享更新。在* 0 ..上,你是對的我已經更新了它* 1 ...沒有發現自己有幸保持封閉的道路,並且必須保持開放式結束。 – hemant

0

做了幾個更多按照上面Brian所建議的那樣調整我的查詢。並發現查詢響應時間有所改善。現在,與我的原始查詢相比,它的執行時間幾乎佔用了20%的時間,與查詢執行期間我之前共享的查詢相比,當前查詢的db命中次數減少了近60%。 PFB的更新查詢:

MATCH (n:nodeA{key:905728}) 
MATCH path = n-[:rel1|rel2|rel3|rel4*1..]->(c:nodeA)-[:rel5*0..1]->(b:nodeA) 
WHERE ALL(a in nodes(path) where 1=length (filter (m in nodes(path) where m=a))) 
and (length(path) > 0) 
and ((exists ((c)-[:rel5]->(b)) and (not ((c)-[:rel1|rel2|rel3|rel4]->()) OR ANY (x in nodes(path) where (c)-[]->(x)))) 
    OR (not exists ((c)-[:rel5]->()) and (not ((c)-[:rel1|rel2|rel3|rel4]->()) OR ANY (x in nodes(path) where (c)-[]->(x))))) 
RETURN distinct EXTRACT (rp in Rels(path)| type(rp)), EXTRACT (p in NODES(path)| p.key); 

並觀察到從* 1 ..到* 1..15的路徑上限時的戲劇性改善。另外,從查詢中刪除了一個過濾器,這也需要更長的時間。 但是,當查詢的關係超過18-20深度的節點時查詢響應時間增加。

我會建議經常使用配置文件命令來查找查詢中的痛點。這將有助於您更快地解決問題。 謝謝Brian。