高效添加关系。Neo4j
我有一个大约有500万行和两列的CSV文件,列名分别是“client”(客户)和“product”(产品)。每个客户和产品在我的neo4j图数据库中都有一个对应的ID。这里面可能会有各种重复的情况,这没问题。
我在Python中写了以下代码:
j=1
batch_size=500
nbatch=len(client_product)//batch_size+1
for i in range(0,len(client_product),batch_size):
j+=1
print(f"{j}/{nbatch}")
batch = client_product.iloc[i:i + batch_size]
my_dict = batch.to_dict('records')
my_dict_str = str(my_dict)
my_dict_str=dictToPropertiesSingleValue(str(my_dict))
tq=f"""UNWIND {my_dict_str} AS row
MATCH (n:client), (k:product)
WHERE ID(n) = row.client_ID AND ID(k) = row.product_ID
CREATE (n)-[r:client_product]->(k)
return count(r)"""
runq(tq)
中间的部分
my_dict = batch.to_dict('records')
my_dict_str = str(my_dict)
my_dict_str=dictToPropertiesSingleValue(str(my_dict))
是把一个字典格式化成neo4j可以读懂的列表。就像这样:
[ {client_ID: 918906,product_ID: 40320},
{client_ID: 918920,product_ID: 40320},
{client_ID: 918921,product_ID: 40320},
{client_ID: 918953,product_ID: 40321},
{client_ID: 918955,product_ID: 40322},
{client_ID: 918960,product_ID: 40323},
{client_ID: 919018,product_ID: 40323},
{client_ID: 919517,product_ID: 40323},
{client_ID: 919702,product_ID: 40323},
{client_ID: 919703,product_ID: 40324},
{client_ID: 919743,product_ID: 40324},
{client_ID: 919744,product_ID: 40324},
{client_ID: 919745,product_ID: 40324},
{client_ID: 919764,product_ID: 40325}]
我真的很难找到一个更快的方法来上传这些数据。上传几百万条关系应该只需要几分钟,但我现在却要花4个小时。有没有什么建议?
1 个回答
1
其实你不需要写特别复杂的代码来执行10,000个单独的Cypher查询,这就是为什么会花那么长时间。你可以只用一个查询,利用LOAD CSV这个功能,它专门用来直接从CSV数据导入。你还可以使用在事务中调用子查询,这样可以支持批量导入大量数据。
举个例子(我使用的批量大小是5000,但你可以尝试不同的数值,看看哪个速度更快):
LOAD CSV WITH HEADERS FROM 'file:///client_product.csv' AS r
CALL {
WITH r
MATCH (n), (k)
WHERE ID(n) = r.client_ID AND ID(k) = r.product_ID
CREATE (n)-[:client_product]->(k)
} IN TRANSACTIONS OF 5000 rows
注意事项: