Cypher Query其中2个不同的标签不包含与第3个标签/节点的关系

时间:2017-07-18 18:12:57

标签: neo4j cypher neo4jrb

我有3个标签,A,B和Z.A& B都与Z有关系。我想找到所有没有共享任何节点Z的A节点与B共同

目前,正常查询关系存在的位置是有效的。

MATCH (a:A)-[:rel1]->(z:Z)<-[:rel2]-(b:B { uuid: {<SOME ID>} })
RETURN DISTINCT a

但是当我做的时候

MATCH (a:A)
WHERE NOT (a)-[:rel1]->(z:Z)<-[:rel2]-(b:B { uuid: {<SOME ID>} }))
RETURN DISTINCT a

它会抛出错误

Neo4j::Server::CypherResponse::ResponseError: z not defined

不确定此语法是否不正确,我尝试了WHERE NOT EXIST(),但没有运气。

该查询是使用neo4jrb /(Neo4j :: Session.query)通过rails app调用的较大查询的一部分

2 个答案:

答案 0 :(得分:4)

这是与查询范围有关的问题。当您在MATCH子句中描述节点时,如下所示

MATCH (n:SomeLabel)

您告诉cypher要查找标签为SomeLabel的节点,并在查询的其余部分将其分配给变量n,并且在查询结束时,您可以使用RETURN n返回存储在此节点中的值(除非您将n放在WITH子句中,否则将其删除。)

稍后在您查询中,如果您想要MATCH另一个节点,则可以参考n来执行此操作,例如:

MATCH (m:SomeOtherLabel)-[:SOME_RELATIONSHIP]-(n)

将变量连接(在任何方向上)与节点n匹配,标签为SomeOtherLabel,并将其分配给变量m以用于查询的其余部分。< / p>

您只能在MATCH和{OPTIONAL MATCH中的MERGECREATEWITHUNWIND和{类别}中将节点分配给此类变量1}}条款(有人在这里纠正我,如果我错过了一个,我想你也会在列表理解和FOREACH条款中这样做。)

在第二个查询中,您尝试查找标签为A的节点,该节点未连接到标签为Z的节点。但是,您编写查询的方式意味着您实际上是在说找到标记为A的节点,该节点未通过rel1关系连接到存储为z的节点即可。这将失败(如图所示,neo抱怨z未定义),因为您无法在WHERE子句中创建这样的新变量。

要更正错误,您需要删除对变量z的引用,并确保您还在b子句之前定义了包含节点的变量WHERE。现在,您将标签保留在查询中,如下所示。

MATCH (a:A)
MATCH (b:B { uuid: {<SOME ID>} })
WHERE NOT (a)-[:rel1]->(:Z)<-[:rel2]-(b) // changed this line
RETURN DISTINCT a

运气好的话,现在可以了。

答案 1 :(得分:2)

您收到错误,因为z是您在尚未识别的where子句中使用的节点的标识符。

既然你知道 b ,我会先匹配它,然后在你的where子句中使用它。您不需要为:Z分配标识符,只需使用节点标签就足够了。

MATCH (b:B { uuid: {<SOME ID>} })
WITH b
MATCH (a:A)
WHERE NOT (a)-[:rel1]->(:Z)<-[:rel2]-(b)
RETURN DISTINCT a