密码查询,其中 2 个不同的标签不包含与第 3 个 label/node 的关系

Cypher Query where 2 different labels do not contain a relationship to a 3rd label/node

我有 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() 但没有成功。

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

您收到错误消息是因为 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

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

MATCH (n:SomeLabel)

你告诉 cypher 寻找一个标签为 SomeLabel 的节点,并在查询的其余部分将其分配给变量 n,并在查询结束时,您可以使用 RETURN n return 存储在此节点中的值(除非您通过不将其包含在 WITH 子句中来删除 n)。

稍后在查询中,如果您想MATCH另一个节点,您可以参考n来完成,例如:

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

将匹配连接(在任何方向)到节点 n 的变量,标签为 SomeOtherLabel,并将其分配给变量 m 用于查询的其余部分.

您只能在 MATCHOPTIONAL MATCHMERGECREATEWITH 中将节点分配给这样的变量UNWIND 个子句(如果我错过了一个,请有人在这里纠正我,我想你也在列表理解和 FOREACH 个子句中这样做)。

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

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

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

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