2017-08-03 207 views
0

的列表我有,其中ID是节点的数字小id和ID的流是相邻节点的ID的列表。 我使用此查询从这样的流UPSERT节点:Neo4j的创建边缘

WITH ${ids.mkString("[", ",", "]")} as ids 
UNWIND ids as u2id 
MERGE (u1:User {Id:${id}}) 
MERGE (u2:User {Id:u2id}) 
CREATE UNIQUE p = (u1) - [:FRIEND] -> (u2) 

,我有索引标识标签上

CREATE INDEX ON :User(Id) 

的IDS列表长度平均约为100-200。

现在有约6000万个节点和mil。数据库中的边。插入的速度大约是每秒。 Neo4j运行在Core i5,28Gb RAM和2Tb WD Black的专用机器上。

我不知道如何优化插入查询或改善硬件的任何提示。

+0

几个问题... 1)是流不变(这并不是说你可以在一个CSV文件中的所有更新说的和做LOAD CSV)? 2)用户(Id)仅仅是一个索引还是唯一的约束? 3)你是否真的创建了新用户(MERGE暗示)? 4)你可以添加一个这样的执行PROFILE的扩大图像? –

+0

对不起,迟来的答案,1)是真正的流2)索引3)是,创建4)不幸的是数据库目前无法访问 –

回答

1

这些渐进式更改应使查询更快。

  1. 执行MERGEu1的只是一次

    通过UNWIND之前移动的u1MERGE,它只会被执行一次(而不是每一次u2id值)。

    MERGE (u1:User {Id:${id}}) 
    WITH u1, ${ids.mkString("[", ",", "]")} as ids 
    UNWIND ids as u2id 
    MERGE (u2:User {Id:u2id}) 
    CREATE UNIQUE (u1)-[:FRIEND]->(u2) 
    
  2. 此外,使用MERGE代替CREATE UNIQUE

    您的关联性创建使用情况应该是MERGE以及CREATE UNIQUE满足的(因为你确保事先存在的两个端点)。在我的分析中,我看到MERGE使用较少的数据库命中(您的里程可能会有所不同,具体取决于您的数据库特性和neo4j版本)。

    MERGE (u1:User {Id:${id}}) 
    WITH u1, ${ids.mkString("[", ",", "]")} as ids 
    UNWIND ids as u2id 
    MERGE (u2:User {Id:u2id}) 
    MERGE (u1)-[:FRIEND]->(u2) 
    
+0

感谢您的建议,移动MERGE以外UNWID真的加快查询。但是,当节点的数量变成~1亿密尔。 Node4j进程开始交换并且速度急剧下降,所以我们决定写入文件并稍后处理它们:( –