2016-09-13 49 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翻译,然后其余部分由专门的专用数据库代码处理。如果您能够在应用程序级别提供更快的方式来完成此任务,则应该编写一个竞争数据库。

相关问题