密码查询,其中 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
用于查询的其余部分.
您只能在 MATCH
、OPTIONAL MATCH
、MERGE
、CREATE
和 WITH
中将节点分配给这样的变量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
运气好的话,现在可以用了。
我有 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
用于查询的其余部分.
您只能在 MATCH
、OPTIONAL MATCH
、MERGE
、CREATE
和 WITH
中将节点分配给这样的变量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
运气好的话,现在可以用了。