我正在尝试通过使用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语句。这似乎很慢,每秒只添加几个关系。
那么,有更好的方法吗?我完全偏离了这里吗?我查看this question,但这并没有解释如何使用cypher有效地加载节点。我看到的其他所有内容似乎都使用了java,而没有显示可以使用的实际密码查询。
答案 0 :(得分:6)
不要在结束前创建索引(在2.0中)。它会减慢节点的创建速度。
您是否在Cypher中使用参数?
我想你会丢失很多密码解析时间,除非你的密码每次都带有参数完全相同。如果您可以将其建模,那么您将看到显着的性能提升。
您已经在cypher请求中发送了相当大的块,但批量请求API将允许您发送多个REST请求,这可能更快(尝试它!)。
最后,如果这是一次性导入,您可以考虑使用批量导入工具 - 即使在坏的硬件上也可以在几分钟内刻录500K节点...然后您可以升级数据库文件(I不要认为它可以创建2.0文件,但如果没有,可能很快就会出现),并通过Cypher创建标签/索引。
更新:我刚才注意到你的MATCH声明。你不应该这样做 - 一次做一个关系,而不是使用OR的OR。这可能会有很大帮助 - 并确保您使用uids的参数。即使使用索引提示,Cypher 2.0似乎也无法使用OR进行索引查找。也许这会在以后发生。
2013年12月更新:2.0具有Cypher事务端点,我看到了吞吐量大幅提升。我已经能够发送20-30k Cypher语句/秒,使用“exec”大小100-200语句,交易大小总计1000-10000语句。对于加速Cypher的加载非常有效。