Cypher' Node已经存在' MERGE的问题

时间:2016-02-13 15:55:55

标签: neo4j cypher

当我对位置节点的地址有一个独特的约束但是我正在使用合并时,我预先知道为什么我遇到了这个Cypher语句的问题,如果它存在并且只返回其余的id的声明。我错过了什么?

以下是我的发言:

MERGE(l:Location{location_name:"Starbucks", address:"36350 Van Dyke Ave", city: "Sterling Heights",state: "MI", zip_code:"48312",type:"location",room_number:"",long:-83.028889,lat:42.561152})
CREATE(m:Meetup{meet_date:1455984000,access:"Private",status:"Active",type:"project",did_happen:"",topic:"New features for StudyUup",agenda:"This is a brainstorming session to come with with new ideas for the companion website, StudyUup. Using MatchUup as the base, what should be added, removed, or modified? Bring your thinking caps and ideas!"})
WITH m,l 
MATCH (g:Project{title_slug:"studyuup"}) MATCH (p:Person{username:"wkolcz"})
WITH m,l,g,p  
MERGE (g)-[:CREATED {rating:0}]->(m)
MERGE (m)-[:MEETUP_AT {rating:0}]->(l)-[:HOSTED_MEETUP]->(m)
MERGE (m)<-[:ATTENDING]-(p)
RETURN id(m) as meeting_id

我得到了:

Node 416 already exists with label Location and property "address"=[36350 Van Dyke Ave]

1 个答案:

答案 0 :(得分:19)

您遇到了MERGE的常见误解。 MERGE合并您在单个MERGE子句中指定的所有。所以操作的顺序是:

  1. 使用所有您指定的属性搜索:Location个节点。
  2. 如果找到,请返回节点。
  3. 如果未找到,请创建节点。
  4. 您的问题发生在第3步。由于您指定了所有属性的节点不存在,它将转到步骤3并尝试创建包含所有这些属性的节点。那时你的唯一性约束被违反了。

    最佳做法是合并您已限制为唯一的属性,然后使用SET更新其他属性。在你的情况下:

    MERGE (l:Location {address:"36350 Van Dyke Ave"})
    SET l.location_name = "Starbucks",
         l.city = "Sterling Heights"
    ...
    

    同样的逻辑将适用于您稍后在查询中合并的关系。如果整个模式不存在,它将尝试创建整个模式。这就是你应该坚持最佳做法的原因:

    MERGE (node1:Label1 {unique_property: "value"})
    MERGE (node2:Label2 {unique_property: "value"})
    MERGE (node1)-[:REL]-(node2)