我有一个带有~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 DB上运行"全图扫描"查询时,最佳做法是什么?
谢谢!
这将导致需要在提交之前刷新到磁盘之前首先在内存中建立的巨大事务.
这里的最佳实践是对limit事务的范围并多次调用该语句:
MATCH (n:MyNode)
WHERE NOT HAS (n.newColumn)
WITH n LIMIT 10000
SET n.newColumn=n.c1+n.c2
RETURN count(n)
Run Code Online (Sandbox Code Playgroud)
运行此语句,直到返回结果为0.
要自动化过程中,你可以使用apoc程序问心无愧apoc.periodic.iterate()这样
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}
);
Run Code Online (Sandbox Code Playgroud)