Neo4j 使用py2neo上传数据的最佳方式
我尝试过使用py2neo上传中等大小数据集的方法。在我的例子中,每天需要加载大约80K节点和400K边。我想分享我的经验,并询问社区是否还有更好的方式,我没有遇到过 A.py2neo的“本机”命令。 使用Neo4j 使用py2neo上传数据的最佳方式,neo4j,py2neo,Neo4j,Py2neo,我尝试过使用py2neo上传中等大小数据集的方法。在我的例子中,每天需要加载大约80K节点和400K边。我想分享我的经验,并询问社区是否还有更好的方式,我没有遇到过 A.py2neo的“本机”命令。 使用graph.merge_one()创建节点,并使用push()设置属性。 我很快就放弃了这一点,因为它非常慢,甚至不会在几分钟内超过10K记录。毫不奇怪,py2neo’和一些帖子推荐使用Cypher B.无分区的密码 在循环中使用py2neo.cypher.CypherTransactionap
graph.merge_one()
创建节点,并使用push()
设置属性。
我很快就放弃了这一点,因为它非常慢,甚至不会在几分钟内超过10K记录。毫不奇怪,py2neo’和一些帖子推荐使用Cypher
B.无分区的密码
在循环中使用py2neo.cypher.CypherTransaction
append()
,最后使用commit()
#查询已发送到MSSQL。返回约80K条记录
结果=引擎。执行(查询)
语句=“合并(e:Entity{myid:{ID})集合e.p=1”
#开始新的密码事务
tx=neoGraph.cypher.begin()
对于结果中的行:
tx.append(语句,{“ID”:row.ID_field})
tx.commit()
这会超时并使Neo4j服务器崩溃。
我知道问题是所有80K密码语句都试图一次性执行
C.具有分区和一次提交的密码
我使用计数器和process()
命令一次运行1000条语句
#查询已发送到MSSQL。返回约80K条记录
结果=引擎。执行(查询)
语句=“合并(e:Entity{myid:{ID})集合e.p=1”
计数器=0
tx=neoGraph.cypher.begin()
对于结果中的行:
计数器+=1
tx.append(语句,{“ID”:row.ID_field})
如果(计数器==1000):
tx.process()#处理1000条语句
计数器=0
tx.commit()
这在开始时运行得很快,但随着处理了1000个事务,速度会减慢。最终,它在堆栈溢出中超时。
这是令人惊讶的,因为我期望process()
每次都重置堆栈
D.具有分区的密码,并为每个分区提交
这是唯一有效的版本。对1000个事务的每个分区执行commit()
,并使用begin()
重新启动一个新事务
#查询已发送到MSSQL。返回约80K条记录
结果=引擎。执行(查询)
语句=“合并(e:Entity{myid:{ID})集合e.p=1”
计数器=0
tx=neoGraph.cypher.begin()
对于结果中的行:
计数器+=1
tx.append(语句,{“ID”:row.ID_field})
如果(计数器==1000):
tx.commit()#提交1000条语句
tx=neoGraph.cypher.begin()#重新打开事务
计数器=0
tx.commit()
这运行得又快又好
有什么意见吗?正如您通过反复试验发现的那样,当单个事务的操作数不超过10K-50K时,它的性能最好。您在D中描述的方法最有效,因为您每1000条语句提交一次事务。您可能可以安全地增加批量大小 您可能希望尝试的另一种方法是将值数组作为参数传递,并使用Cypher的
UNWIND
命令对其进行迭代。例如:
WITH {id_array} AS ids // something like [1,2,3,4,5,6]
UNWIND ids AS ident
MERGE (e:Entity {myid: ident})
SET e.p = 1
如果我不使用事务,是否需要提交?当我新建一个数据库时,一切正常。但是,一旦我重新启动neo4j社区服务器,结果是错误的,甚至关系和节点的数量也是错误的。问题是什么?