2

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

目前,在存在关系的情况下进行正常查询是可行的。

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 应用程序调用的更大查询的一部分

4

2 回答 2

4

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

MATCH (n:SomeLabel)

您告诉 cypher 查找带有 label 的节点SomeLabel,并将其分配给查询的其余部分中的变量n,并且在查询结束时,您可以使用返回存储在此节点中的值RETURN n(除非您n通过不包括在一个WITH子句中)。

稍后在您查询时,如果您想要MATCH另一个节点,您可以参考 进行n,例如:

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

将匹配连接(在任何方向)到节点的变量n,带有标签SomeOtherLabel,并将其分配给该变量m以进行其余的查询。

您只能在and子句中将节点分配给诸如MATCH, OPTIONAL MATCH,MERGECREATE(sort of) 之类的变量(如果我遗漏了一个,请在这里纠正我,我想您也可以在列表推导和子句中这样做)。WITHUNWINDFOREACH

在您的第二个查询中,您试图找到一个带有标签的节点,该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

幸运的是,这现在可以工作了。

于 2017-07-18T18:31:03.290 回答
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
于 2017-07-18T18:30:14.563 回答