更新图中的所有节点

时间:2016-03-08 10:07:27

标签: neo4j cypher

我有一个拥有约250M节点的Neo4J数据库(社区版,v2.3.2),我需要运行一个查询来迭代所有节点并更新属性。它不是我常规查询的一部分,而是我必须运行的一次性维护任务。

我可以用Cypher轻松表达它,但看起来Neo4J试图在内存中保留所有节点,然后执行我的SET操作,导致内存耗尽,甚至更糟 - 将整个JVM放入常量GC循环。我有可能让它在foreach循环中运行,一次在一个节点上运行吗?

我的Cypher查询将是:

MATCH (n:MyNode) WHERE NOT HAS (n.newColumn) SET n.newColumn=n.c1+n.c2

我不介意它是否会运行很长时间,只是它不会让服务器本身崩溃。如果Cypher不是完成任务的最佳工具,我也可以使用其他API。

更一般地说 - 当您需要运行"全图扫描"时,最佳做法是什么?查询您的Neo4J数据库?

谢谢!

1 个答案:

答案 0 :(得分:6)

这将导致一个巨大的事务,需要先在内存中建立,然后在提交时刷新到光盘。

这里的最佳做法是limit事务的范围并多次调用该语句:

MATCH (n:MyNode) 
WHERE NOT HAS (n.newColumn) 
WITH n LIMIT 10000
SET n.newColumn=n.c1+n.c2
RETURN count(n)

运行此语句,直到返回结果为止。

要自动执行此过程,您可以使用apoc proceduresapoc.periodic.iterate()这样的<{p}}

call apoc.periodic.iterate(
'MATCH (n:MyNode) WHERE NOT exists(n.newColumn) RETURN n',
'SET n.newColumn=n.c1+n.c2', {batchSize:10000,iterateList:true,parallel:true}
);