使用cypher将节点插入neo4j数据库的最有效方法是什么?



我试图通过使用py2neo python模块(py2neo.cypher.execute)执行cypher命令将大量节点(~500,000)插入(非嵌入式)neo4j数据库。最终,我需要删除对py2neo的依赖,但我现在使用它,直到我了解更多关于cypher和neo4j。

我有两个节点类型A和B,绝大多数节点类型为A。存在两种可能的关系r1和r2,使得A-[r1]-A和A-[r2]-B。A型的每个节点有0 - 100个r1关系,B型的每个节点有1 - 5000个r2关系。

目前,我正在通过构建大型CREATE语句插入节点。例如,我可能有一个语句

CREATE (:A {uid:1, attr:5})-[:r1]-(:A {uid:2, attr:5})-[:r1]-...

的地方……可能还有5000个左右的节点和关系在图中形成线性链。这个可以工作,但是速度很慢。我还使用

对这些节点进行索引
CREATE INDEX ON :A(uid)

添加完所有A类节点后,再次使用CREATE语句添加B类节点。最后,我试图使用像

这样的语句添加r2关系。
MATCH c:B, m:A where c.uid=1 AND (m.uid=2 OR m.uid=5 OR ...)
CREATE (m)-[:r2]->(c)

的地方……可以表示几千个OR语句。这看起来真的很慢,每秒只添加几个关系。

那么,有没有更好的方法来做到这一点呢?我完全跑题了吗?我看了这个问题,但这并没有解释如何使用cypher来有效地加载节点。我看到的其他所有东西似乎都使用java,而没有显示可以使用的实际密码查询。

直到末尾才创建索引(在2.0中)。

您是否在Cypher中使用参数?

我想您会损失大量的密码解析时间,除非您的密码每次都与参数完全相同。如果您可以这样建模,您将看到性能的显著提高。

你已经在你的密码请求中发送了相当大的块,但是批处理请求API将允许你在一个REST请求中发送多个块,这可能会更快(尝试一下!)。

最后,如果这是一次导入,您可以考虑使用批量导入工具——即使在糟糕的硬件上,它也可以在几分钟内烧掉500K个节点……然后你可以升级数据库文件(我不认为它可以创建2.0文件,但可能很快就会出现),并通过Cypher创建你的标签/索引。

Update:我刚刚注意到末尾的MATCH语句。您不应该这样做——一次处理一个关系,而不是对id使用OR。这可能会有很大帮助——并确保您为uid使用了参数。Cypher 2.0似乎无法使用OR进行索引查找,即使使用索引提示也是如此。也许以后会有。

2013年12月更新: 2.0具有Cypher事务端点,我已经看到了很大的吞吐量改进。我已经能够发送20-30k个Cypher语句/秒,使用100-200个语句的"执行"大小,以及总共1000-10000个语句的交易大小。

最新更新