使用NodeJS,我将这些数据收集到Neo4J:
这完全是异步的。 这意味着很多次我可以获得有关数据库中存在的用户和APP的信息。
因此,只需创建项目然后再创建CREATE关系,我需要在USER和APP中为每一行运行MERGE以确保它们在数据库中。在此之后,我可以建立关系。
我发送到/cypher
端点。
params:{props:objects_array},
query:[
' FOREACH (p IN {props} | ',
' MERGE (u:user {id:p._user_id}) SET u.id = p._user_id ',
' MERGE (a:app {id:p._app_id}) SET a.id = p._app_id ',
' MERGE (m:machine {id:p._machine_id}) SET m.id = p._machine_id ',
' MERGE (u)-[:OPENED]->(a) ',
' MERGE (a)-[:USERS]->(u) ',
' MERGE (u)-[:WORK_IN]->(m) ',
' )',
].join("")
这很有效,但速度很慢。 我通过更改每个请求的同时请求和行来控制余额。
同时有5个请求,每个500行,它可以解决4个死锁错误,需要2分钟才能完成5000行。
问题是它一直需要2核CPU到99%(digitalocean 4gb RAM),我需要将其扩展到150个并发请求,而不仅仅是5个。
我认为可能的解决方案是:
答案 0 :(得分:3)
如果您只使用没有唯一约束或索引的MERGE,则需要Neo4j为每个MERGE执行节点空间的完整扫描,以验证给定属性不存在其他项目。这意味着您最终会得到一个非常高的算法复杂度,并且还会受到磁盘限制。
您需要为应该在数据库中唯一的标签/属性元组创建索引或(最好)唯一约束。这应该会显着加快您的MERGE查询速度。
此外,如果您使用新的事务端点(http://docs.neo4j.org/chunked/stable/rest-api-transactional.html)来替换密码端点,那么您会感觉更好。它支持与cypher端点相同的功能,但提高了性能,并且能够为每个HTTP调用运行多个cypher语句,并允许事务在服务器上保持运行,以便为客户端提供长期运行的事务支持。
过去,Neo4j 2.1将在未来几个月内发布,它包含几项性能增强功能,可显着加快并发查询的执行速度。您可能想尝试即将到来的里程碑,看看它对您的表现有何帮助。
答案 1 :(得分:0)
我不知道cypher但是使用neo4j rest api你可以使用batch insertion轻松实现这一点,你也可以在同一批处理中同时创建关系,并在批处理中的后续作业中创建节点。 refer to items created earlier。