Python Neo4j:如何通过cypher删除数据库中的所有重复关系?
我有一个巨大的数据库,有大量的节点(10mil+)。整个数据库中只有一种类型的关系。但是,有大量节点之间存在重复的关系。我现在拥有的是一个cypher脚本,它查找所有具有重复项的对,然后是一个python脚本,它运行并清理每个对(在这些节点之间只留下一个唯一的关系)Python Neo4j:如何通过cypher删除数据库中的所有重复关系?,python,database,neo4j,Python,Database,Neo4j,我有一个巨大的数据库,有大量的节点(10mil+)。整个数据库中只有一种类型的关系。但是,有大量节点之间存在重复的关系。我现在拥有的是一个cypher脚本,它查找所有具有重复项的对,然后是一个python脚本,它运行并清理每个对(在这些节点之间只留下一个唯一的关系) 将(a)-[r]->(b)与a、b、count(*)匹配为c,其中c>1返回a.pageid、b.pageid、c LIMIT 100000 这对于一个小的数据库来说效果相当好,但是当我在一个大的数据库上运行它时,它最终会出现一个异
将(a)-[r]->(b)与a、b、count(*)匹配为c,其中c>1返回a.pageid、b.pageid、c LIMIT 100000代码>
这对于一个小的数据库来说效果相当好,但是当我在一个大的数据库上运行它时,它最终会出现一个异常,即堆内存不足(越来越大的内存不足)
因此,问题有两个方面:
1) 是否有任何类型的索引我可以放在关系上(现在没有),这将有助于加快这一速度?
2) 是否有一个密码查询可以(以快速的方式…或至少可靠地)删除数据库中的所有重复关系,为每个节点对(它们之间已经有关系)只留下一个唯一的关系
另外,我正在ubuntu(12点多)AWS设备上运行neo4j 2.0.1
p.p.S.我意识到有这样一个答案:,但是他问的是更具体的问题(针对2个已知节点),覆盖了完整数据库的答案不再运行(语法更改?)
提前谢谢 链接SO问题中的db global查询有什么错误?试着在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..
这是公认答案的一个版本,已被修复(通过插入WITH rr
子句)以适用于较新的neo4j版本,并且应该更快(因为它仅在需要时创建新的尾部
列表):
[更新]
如果只想删除相同类型的重复关系,请执行以下操作:
MATCH (a)-[r]->(b)
WITH a, b, TYPE(r) AS t, COLLECT(r) AS rr
WHERE SIZE(rr) > 1
WITH rr
LIMIT 100000
FOREACH (r IN TAIL(rr) | DELETE r);
只是想一想:您是否尝试过将较小的批处理(一次100个)传递给python脚本?(不确定您是否需要每次获取100K)您的节点上是否有索引,您可以在其中针对特定节点类型运行此操作,从而减少总节点空间?FOREACH如何知道只杀死额外的节点并留下1个(例如,如果有3个相同的关系,则留下1和杀死2)。我只是想在db上运行之前理解一下(导入此数据花了2周时间:-/首先测试它,在或其他地方设置一个模拟数据库。原因是您只携带集合的尾部,即除第一个以外的所有部分,因此foreach不会触及第一个。它起作用了!!!!以前的努力将持续数小时,最终以堆“内存不足”的方式结束异常。这件事在2.5分钟内完成!!一年后出现语法错误。出于某种原因,Neo4j不喜欢限制100000
MATCH (a)-[r]->(b)
WITH a, b, TYPE(r) AS t, COLLECT(r) AS rr
WHERE SIZE(rr) > 1
WITH rr
LIMIT 100000
FOREACH (r IN TAIL(rr) | DELETE r);