3

对于以下 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 关系?现在,unit 没有被创建,大概是因为 g 为空。

我正在使用 Neo4j Advanced 1.8

谢谢!

4

4 回答 4

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

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

编辑:经过一番尝试,我得出一个结论,您可能想要做 2 个不同的查询,首先是创建与始终存在的唯一节点的关系的第一部分,第二部分是创建与可能不会发生的组的关系:

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 条件(可能是错误?),尽管在我对 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
于 2012-11-06T15:24:02.037 回答
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,则 second 根本不会被执行。甚至这里可能不需要 WHERE g <> null。请尝试并确认

于 2012-11-07T17:50:14.383 回答
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
于 2014-08-10T13:21:13.890 回答
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() 来中断写入。

于 2017-05-23T13:44:03.353 回答