2016-09-13 82 views
0

在neo4j數據庫中存儲有一個樹結構。需要刪除一個包含所有子節點的節點。我可以提出至今兩種方法:使用彈簧數據neo4j刪除具有連接節點的節點的最佳方法是什麼?

  1. 編寫自定義查詢,刪除節點,沿着 與DB水平及其關係的所有兒童。
  2. 刪除節點本身並在單獨的線程上運行遞歸函數以刪除應用程序級別的所有子節點及其關係。

有人可以估計這些方法的有效性,並確定哪一個更好(更快)沒有基準?

回答

1

方法#2,使用線程同時刪除同一子圖中的節點/關係,很容易出錯,應該避免。

刪除關係時,neo4j的默認鎖定機制將鎖定關係及其端點;當多個線程同時嘗試刪除同一子圖中的節點/關係時,這可能會導致死鎖錯誤。另外,線程可能會發現它正在嘗試工作的節點/關係已經消失(由於其他線程的操作)。

以下是使用方法#1的示例Cypher查詢。它應該找到所有不同節點的Foo/BAR樹和刪除樹(使用DETACH DELETE,這@ToreEschliman還建議):

將帖子

MATCH p=(a:Foo {id: 123})-[:BAR*0..]->(b:Foo) 
WITH COLLECT(b) AS ns1 
UNWIND ns1 AS n 
WITH COLLECT(DISTINCT n) AS ns2 
FOREACH(y IN ns2 | DETACH DELETE y); 

[更新]

基於新信息從註釋中,這裏是如何刪除在特定CodeSet節點爲根的整棵樹:

MATCH p=(root:CodeSet {id: 123})<-[*0..]-(node) 
DETACH DELETE p; 

使用的MATCH模式假定所有後代節點都通過指向根節點的關係進行連接。

+1

我可能會錯過一些東西。是否有某些原因導致您無法收集b並在該集合上使用您的FOREACH DETACH DELETE而不是收集每個匹配路徑中的所有節點?似乎用你的方法會有大量的重複,即使你的DISTINCT處理這個問題,我想知道這是怎麼回事。 – InverseFalcon

+2

@InverseFalcon:謝謝。我編輯了我的答案,使用'COLLECT(b)'而不是'REDUCE(s = [],x IN NODES(p)| s + x)',這確實應該更快。但是'ns1'仍然可以包含重複項,所以查詢的其餘部分是相同的。 – cybersam

+0

@cybersam我嘗試了更新的查詢和原始的。 orignal查詢適用於我,而更新的查詢只是刪除關係(將節點分離)。非常感謝您的時間。 – Polyakoff

1

你可以估計,是的,你應該估計第一個總是更快。如果你可以編寫一個查詢來標識你所有的壞節點,那麼只需要這樣做,然後在最後使用DETACH DELETE這些節點。一個事務,一個Cypher翻譯,然後其餘部分由專門的專用數據庫代碼處理。如果您能夠在應用程序級別提供更快的方式來完成此任務,則應該編寫一個競爭數據庫。

相關問題