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

Wal*_*lcz 6 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
Run Code Online (Sandbox Code Playgroud)

我正进入(状态:

Node 416 already exists with label Location and property "address"=[36350 Van Dyke Ave]
Run Code Online (Sandbox Code Playgroud)

Nic*_*ite 22

你遇到了一个常见的误解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"
...
Run Code Online (Sandbox Code Playgroud)

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

MERGE (node1:Label1 {unique_property: "value"})
MERGE (node2:Label2 {unique_property: "value"})
MERGE (node1)-[:REL]-(node2)
Run Code Online (Sandbox Code Playgroud)

  • 嗨妮可!感谢您的洞察力。我意识到我必须添加了一个额外的属性(或删除了一个),它只导致部分匹配,然后导致与约束的冲突。谢谢! (2认同)
  • 这是一个非常有用的答案,我在尝试抱怨的"LOAD CSV"后发现了这个答案. (2认同)