Neo4j:如何通过cypher删除数据库中的所有重复关系?

时间:2014-04-10 17:57:46

标签: python database neo4j

我有一个拥有大量节点(10mil +)的庞大数据库。整个数据库中只有一种关系。但是,有大量节点在它们之间存在重复关系。我现在拥有的是这个cypher脚本,它找到所有带有重复项的对,然后是一个运行并清理每个对的python脚本(在这些节点之间只留下一个唯一的关系)。

match (a)-[r]->(b) with a,b, count(*) as c where c>1 return a.pageid, b.pageid, c LIMIT 100000;

这对于一个小型数据库来说效果相当不错,但是当我在一个大型数据库上运行它时,它最终会因为堆上内存不足而异常爆炸(越来越多的盒子没有帮助)。

所以,问题是双重的: 1)是否有任何类型的索引我可以建立关系(现在没有),这将有助于加快这一点? 2)是否存在能够(以快速方式......或至少可靠地)删除数据库中所有重复关系的密码查询,每个节点对只有一个唯一的关系(已经有它们之间的关系)?

P.S。我在一个ubuntu(12something)AWS盒子上运行neo4j 2.0.1。

P.P.S。我意识到有这样的答案:stackoverflow,但是他所要求的是更具体的东西(针对2个已知的节点),并且已经覆盖完整数据库的答案不再运行(语法更改?)

提前致谢!

2 个答案:

答案 0 :(得分:8)

您在链接的SO问题中使用db全局查询会出现什么错误?尝试用|替换:中的FOREACH,这是我能看到的唯一突破性语法差异。 2.x方式说同样的事情,除了适应你在db中只有一种关系类型,可能是

MATCH (a)-[r]->(b)
WITH a, b, TAIL (COLLECT (r)) as rr
FOREACH (r IN rr | DELETE r)

我认为WITH管道在没有重复的情况下会带有空尾,而且我不知道循环一个空集合是多么昂贵 - 我的意思是引入的地方限制是在WITH之后使用过滤器,类似于

MATCH (a)-[r]->(b)
WITH a, b, TAIL (COLLECT (r)) as rr
WHERE length(rr) > 0 LIMIT 100000
FOREACH (r IN rr | DELETE r)

由于这个查询根本没有触及属性(与你的相反,它返回(a)和(b)的属性)我不认为它对于中等图形来说应该是非常重要的内存和你的一样,但你必须试验这个限制。

如果内存仍然存在问题,那么如果有任何方法限制要使用的节点(不涉及属性),那也是个好主意。如果您的节点可通过标签区分,请尝试在此时运行一个标签的查询

MATCH (a:A)-[r]->(b) //etc..
MATCH (a:B)-[r]->(b) //etc..

答案 1 :(得分:0)

这是已接受的答案的一个版本,已得到修复(通过插入WITH rr子句),以便与最新的neo4j版本一起使用,并且应该更快(因为它仅创建新的{{1} }(在需要时列出):

TAIL

[更新]

如果您只想删除具有相同类型的重复关系,请执行以下操作:

MATCH (a)-[r]->(b)
WITH a, b, COLLECT(r) AS rr
WHERE LENGTH(rr) > 1
WITH rr
LIMIT 100000
FOREACH (r IN TAIL(rr) | DELETE r);