2016-02-13 67 views
3

我很困惑,为什么我得到这个Cypher语句的问题,当我对位置节点的地址有一个唯一的约束,但我正在使用一个合并,应该发现,如果它存在并且仅返回该表述的其余部分的id。我错过了什么?Cypher'Node已经存在问题与MERGE

这里是我的发言:

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] 

回答

6

您所遇到的MERGE一个普遍的误解。 MERGE合并在的一切您已在单个MERGE条款中指定。因此,操作顺序是:

  1. 搜索一个:Location节点与所有您指定的属性。
  2. 如果找到,则返回节点。
  3. 如果找不到,请创建节点。

您的问题发生在第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) 
+0

嘿妮可!感谢您的洞察力。我意识到我必须添加一个额外的属性(或删除一个),导致只有部分匹配,然后导致与约束的冲突。谢谢! –

+0

这是一个超级有用的答案,我在尝试一个抱怨的LOAD CSV后找到了答案。 – vielmetti