我有1.3亿个带标签的节点Snp.我想将财产转换position从string到int所有节点.我正在使用neo4j 3.0.4与apoc版本3.0.4.1.
由于节点数量很大,这必须分批完成.我尝试了这个apoc.periodic.rock_n_roll()程序
CALL apoc.periodic.rock_n_roll(
'MATCH (n:Snp) WITH n RETURN id(n) AS id_n',
'MATCH (n:Snp) where id(n)={id_n} SET n.position = toInt(n.position)',
20000
)
Run Code Online (Sandbox Code Playgroud)
我认为这会批量匹配所有节点,然后为每个批次调用第二个查询.但它会阻止neo4j频繁使用GC并增加内存使用量.该程序尚未在3小时内完成.
如果第一个MATCH是有限的,它可以工作,以下需要大约20秒:
CALL apoc.periodic.rock_n_roll(
'MATCH (n:Snp) WITH n LIMIT 1000000 RETURN id(n) AS id_n',
'MATCH (n:Snp) where id(n)={id_n} SET n.position = toInt(n.position)',
20000
)
Run Code Online (Sandbox Code Playgroud)
但是,这不是我认为的程序.我能以某种方式以不同方式使用它来转换大量节点的属性吗?
您传递给该apoc.periodic.rock_n_roll过程的第一个Cypher语句将尝试获取所有1.3亿个Snp节点.这可能是您看到高内存使用率和缓慢处理的原因.批处理仅在第二个Cypher语句上执行.
该apoc.periodic.commit程序应该更好地适用于您的用例.以下调用将一次获取并转换100K节点,直到它们全部被处理完毕.
CALL apoc.periodic.commit(
'MATCH (n:Snp) WHERE TOINT(n.position) <> n.position WITH n LIMIT {limit} SET n.position = TOINT(n.position) RETURN COUNT(*);',
{limit: 100000}
)
Run Code Online (Sandbox Code Playgroud)
该apoc.periodic.commit过程重复调用其Cypher查询,直到它返回0.该MATCH子句过滤掉已经有整数的节点position.该limit参数指定批量大小.