我已经在Linux本地服务器上的Ubuntu 14.04上安装了Neo4j社区版3.0.3,并已成功安装它。现在我通过Windows浏览器通过该服务器上的端口7474访问它。
现在我有一个csv文件,其中包含以下格式的销售订单数据:
Customer_id, Item_id, Order_Date
它有90000行,customer_id和item_id都是节点。总共(30000个customer_id + 30000 item_ids)节点和90000个关系(order_date作为距离属性名称)。我运行以下查询将csv中的数据插入到我的图形数据库中:
LOAD CSV WITH HEADERS FROM "file:///test.csv" AS line
MERGE (n:MyNode {Name:line.Customer})
MERGE (m:MyNode {Name:line.Item})
MERGE (n) -[:TO {dist:line.OrderDate}]-> (m)
我让它继续运行,大约7到8个小时后,它仍在运行。我的问题是,我做错了吗?我的查询没有优化?或者这件事通常吗?我是Neo4j和Cypher的新手。请帮帮我。
答案 0 :(得分:2)
创建唯一性约束
您应该在MyNode.Name
:
CREATE CONSTRAINT ON (m:MyNode) ASSERT m.Name IS UNIQUE;
除了强制MyNode
的数据完整性/唯一性之外,还将在MyNode.Name
上创建索引,这将加快MERGE
语句的查找速度。 indexes and performance section here中有更多信息。
使用定期提交
由于Neo4j是一个事务性数据库,因此查询结果将在内存中构建,并且整个查询将立即提交。根据计算机上可用数据/资源的大小,您可能希望使用periodic commit functionality in LOAD CSV
来避免在内存中构建整个语句。只需使用USING PERIODIC COMMIT
开始查询即可。这将定期提交结果,在迭代CSV文件时释放内存资源。
避免急切
您的查询存在一个问题,即包含eager operation。这将阻碍定期提交功能,无论如何,事务都将构建到内存中。为避免急切操作,您可以在csv文件中使用两次传递:
一旦创建节点:
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///test.csv" AS line
MERGE (n:MyNode {Name:line.Customer})
MERGE (m:MyNode {Name:line.Item})
然后再次建立关系:
LOAD CSV WITH HEADERS FROM "file:///test.csv" AS line
MATCH (n:MyNode {Name:line.Customer})
MATCH (m:MyNode {Name:line.Item})
MERGE (n) -[:TO {dist:line.OrderDate}]-> (m)
至少需要创建唯一性约束 - 这应该足以提高LOAD CSV
语句的性能。