Neo4j Cypher:仅在端节点存在时创建关系

时间:2012-11-06 05:24:39

标签: neo4j cypher

以下Cypher声明:

start n=node:types(id={typeId}), g=node:groups(id={groupId})
create unique (n)<-[:has_type]-(unit {props})-[:has_group]->(g)
return unit

有些情况下g可能为null(即不存在id groupId的组)。 在这种情况下,我该怎么做才能使这个语句仍然创建单元,但跳过与g的has_group关系? 现在,单位不会被创建,大概是因为g为空。

我正在使用Neo4j Advanced 1.8

谢谢!

4 个答案:

答案 0 :(得分:1)

我建议将g的定义移到where子句,因为从不存在的节点开始会产生错误,因此无法继续查询到创建阶段。注意'?'它处理Cypher中的空值:

 start n=node:types(id={typeId})
 create unique (n)<-[:has_type]-(unit {props})-[:has_group]->(g)
 where g.id?={groupId}
 return unit

查询可能需要一些调整,这只是我第一次未经测试的镜头。

编辑经过一番尝试,我得出结论,你可能想要做两个不同的查询,首先是创建与唯一节点的关系的第一部分,这是唯一的节点,第二部分是创建可能不会发生的与该团体的关系:

start n=node:types(id={typeId})
create unique (n)<-[:has_type]-(unit {props})    
return unit

start unit=node:unitProps({unitPropsValue}) ,g=node:groups(id={groupId}) 
create unique unit-[:has_group]->g    
return g

如果该组不存在,第二个查询将失败并显示错误,但这并不重要,因为您仍将到达目标。由于一些奇怪的原因,我无法像在第一次尝试中尝试的那样在where子句中实现一些限制。以下查询似乎只是跳过where条件(也许是一个bug?)虽然在我理解Cypher时它应该匹配已经存在的组,但它确实创建了一个新的g节点:

start n=node(1) 
create unique n-[:TYPE1]-(uniq {uid:333})
with uniq
create unique uniq-[:TYPE2]->g 
where has(g.gid) and g.gid=999 
return g

答案 1 :(得分:0)

您可以使用WITH子句在一个查询中实现此目的,

start n=node:types(id={typeId})
create unique (n)<-[:has_type]-(unit {props})
WITH unit
START g=node:groups(id={groupId})
create unique (unit)-[:has_group]->(g)
WHERE g <> null
return unit

如果g为null,则第二个不会被执行。甚至在哪里g&lt;&gt;这里可能不需要null。请尝试并确认

答案 2 :(得分:0)

你可以试试这个

   MATCH (g:groups) 
   WHERE id(g)={groupId}
   create unique (unit {props})-[:has_group]->(g)
   WITH unit, create unique (unit)-[:has_type]->(n)
   return unit

答案 3 :(得分:0)

由于这是我能找到的与此相关的唯一内容,我将添加我正在处理的内容,因为其他答案都不足以满足我的目的。

MATCH (a:TEST{id:1}) 
OPTIONAL MATCH (b:TEST)
WHERE b.id IN [2,3,5]
// collect b so that there are no nulls, and rows aren't lost when no match
WITH a, collect(b) AS c
FOREACH(n IN c | CREATE UNIQUE (a)-[:HAS]->(n))
RETURN a

适用于Cypher 2.3+(我不能在此之前测试)

对于那些有APOC的人,你也可以使用CALL apoc.cypher.doIt()来打破写作。