如何批量执行Neo4j Cypher查询

4

我有超过1.3亿个某种类型的节点和50万个另一种类型的节点,我试图按以下方式创建它们之间的关系:

MATCH (p:person)
MATCH (f:food) WHERE f.name=p.likes
CREATE (p)-[l:likes]->(f)

问题在于已创建了1.3亿个关系,我希望以类似于LOAD CSV时使用的PERIODIC COMMIT方式来执行此操作。是否有这样一种针对我的查询类型的功能?
1个回答

3
是的,有的。您需要安装APOC Procedures库在此下载)。您将使用作业管理部分中的apoc.periodic.commit()函数。文档中如下所述:

CALL apoc.periodic.commit(statement, params) - 重复批量更新语句,直到返回0,该过程是阻塞的

您需要结合LIMIT子句和将limit值作为参数来使用它。
但是,为了获得最佳结果,您需要确保连接数据(例如f.name)具有索引或唯一约束条件,以大幅减少时间。
以下是您可能会使用的示例(假设根据您的示例,一个人只喜欢一种食物,并且我们应该仅将其应用于尚未设置关系的:persons):
CALL apoc.periodic.commit("
MATCH (p:person)
WHERE p.likes IS NOT NULL
AND NOT (p)-[:likes]->(:food)
WITH p LIMIT {limit}
MATCH (f:food) WHERE p.likes = f.name
CREATE (p)-[:likes]->(f)
RETURN count(*)
", {limit: 10000})

这里有一个更新,APOC Procedures 已经发展和改进了,批处理能力也得到了提高。在几乎所有情况下,应该优先选择 [apoc.periodic.iterate()[(https://neo4j-contrib.github.io/neo4j-apoc-procedures/#commit-batching),因为它更高效、更易于使用。使用它时更难犯愚蠢的错误。 - InverseFalcon
我正在使用Neo4j企业版3.5.x。有没有不使用APOC的方法来完成这个任务? - Artan M.
对于3.5.x版本而言,如果没有APOC插件,你只能通过在客户端代码中自行分批处理,并针对每个批次发出单独的Cypher查询来实现此功能。在后续的4.x版本中,你可以使用CALL {} IN TRANSACTIONS来进行批处理。 - InverseFalcon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接