使用密码删除neo4j中的所有节点和关系超出堆空间

Posted

技术标签:

【中文标题】使用密码删除neo4j中的所有节点和关系超出堆空间【英文标题】:Deleting all nodes and relationships in neo4j using cypher exceeds heap space 【发布时间】:2013-01-19 09:01:10 【问题描述】:

我一直在尝试按照 neo4j 谷歌组和其他在线资源中的建议运行此查询:

开始 n = 节点(*) 匹配 n-[r?]-() 其中 ID(n)>0 删除 n, r;

为了删除测试之间的所有节点和关系。当我从控制台执行此操作时,我用完了 java 堆空间。当我从 python 执行此操作时(使用新出现的 graph_db.clear(),它使用相同的查询),我得到一个“SystemError:None”,我认为这是相同的 java 堆空间错误。我有一个包含 500k 个节点、只有 5k 个关系和 7M 个属性的数据库。我正在使用 neo4j-1.8.1 的 Mac 笔记本电脑 (10.6.8) 上运行 8GB RAM。我想我有点惊讶删除节点(基本上没有关系,所以非常小的子图)会超过 java 堆空间,但我对 neo4j 的工作原理非常天真。任何有关如何前进的建议表示赞赏。我确实知道数据目录中的 rm -rf 并从头开始会起作用,但我认为可能有一个不太激进的解决方案。

[交叉发布到 neo4j 谷歌群组]

【问题讨论】:

在 WITH 后分页更加方便和明智:START n = node(*) MATCH n-[r?]-() WITH n,r LIMIT 10000 DELETE n, r; @MichaelHunger 不应该是:START n = node(*) WITH n LIMIT 10000 MATCH n-[r?]-() DELETE n, r;? 【参考方案1】:

上面的 cypher 语句导致所有节点(除了 ID 为 0 的根节点之外)在一个事务中在删除之前被实例化。当使用 500k 个节点时,这会占用太多内存。

尝试将要删除的节点数量限制在 10k-50k 左右,例如:

START n = node(*) 
MATCH n-[r?]-() 
WHERE (ID(n)>0 AND ID(n)<10000) 
DELETE n, r;

START n = node(*) 
MATCH n-[r?]-() 
WHERE (ID(n)>0 AND ID(n)<20000) 
DELETE n, r;

等等

但是,删除整个数据库目录并没有什么问题,这是一种很好的做法。

【讨论】:

是的,+1 删除数据库文件夹。 我应该想到限制删除中的节点数。感谢您的提示。不过,显然,要走的路似乎是删除数据库目录。 问号不再用于可选模式。在 Neo4j 的最新版本中,有必要将 match 子句更改为: OPTIONAL MATCH n-[r]-() Read START 也正在逐步淘汰,因此它将是 MATCH (n) OPTIONAL MATCH (n)-[r]->() DELETE n,r 我也必须同意。当我试图提出正确的架构时,我发现自己不断删除数据库......这在很多方面都是一个反复试验的过程。【参考方案2】:

问号不再起作用。使用可选匹配..以下应该可以工作。

               START n = node(*) 
               OPTIONAL MATCH n-[r]-() 
               WHERE (ID(n)>0 AND ID(n)<10000) 
               DELETE n, r;

【讨论】:

为此 +1。在上面的示例中,您将收到“问号不再用于可选模式 - 请改用 OPTIONAL MATCH”。【参考方案3】:

根据 neo4j 文档,图的删除是通过以下方式完成的:

MATCH (n)
OPTIONAL MATCH (n)-[r]-()
DELETE n,r;

为避免 java 堆空间错误,我将此代码与 LIMIT 结合使用:

MATCH (n)
OPTIONAL MATCH (n)-[r]-()
WITH n,r LIMIT 100000 DELETE n,r;

它可以减少节点数量,最终让我们使用第一个、推荐的和更通用的代码。

【讨论】:

【参考方案4】:

从 Neo4j 2.3.3 开始,引入了一种删除节点和关系的新方法。见2.3.3 Docs。

例如,你可以这样做:

MATCH(n) DETACH DELETE n;

【讨论】:

这适用于小型数据集,但在大型数据库上耗尽了我的 Java 堆空间【参考方案5】:

您可以在neo4j 属性中增加堆空间并启用 gc 日志并观察堆空间的上升(如果它真的接近上限)。 页面缓存大小需要根据您的初始大小减少或增加。 ...减少/增加它并检查对加载时间的影响。 neo4j 是内存不足...需要尽可能大的堆大小。

【讨论】:

【参考方案6】:

我在 Neo4J 知识库 [1] 中找到了更好的解决方案:

CALL apoc.periodic.iterate(
    "MATCH (n) RETURN n",
    "DETACH DELETE n",
    batchSize:1000
)
YIELD batches, total RETURN batches, total

[1] - https://neo4j.com/developer/kb/large-delete-transaction-best-practices-in-neo4j/

【讨论】:

以上是关于使用密码删除neo4j中的所有节点和关系超出堆空间的主要内容,如果未能解决你的问题,请参考以下文章

Neo4j - 无法删除节点 - 获取 java.lang.OutOfMemoryError:Java 堆空间

Neo4j 图形数据库 java.lang.OutOfMemoryError:Java 堆空间。 Neo4j 图数据库

Neo4j 密码查询以获取与特定其他节点没有关系的所有节点

OutOfMemoryError:Neo4j 中的 Java 堆空间

OutOfMemoryError:Neo4j中的Java堆空间

neo4j cypher 节点可以模糊匹配么