首页 > 解决方案 > Neo4j Graph Academy,练习 4,第 5 部分:相似查询不同的结果,为什么?

问题描述

在 Graph Academy 中,我们有练习 4,第 5 部分和这个问题: 2. 检索其中一位演员还导演了电影的电影及其演员,返回演员姓名、导演姓名和电影名称。

我试过这个:

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(d:Person)
WHERE exists((d)-[:ACTED_IN]->(m))
RETURN p.name, d.name, m.title

结果似乎还可以,除了重复的信息。 我的结果

在我的结果之后,我看到了来自图形学院的预期查询,它有一些小的变化,将 DIRECTED 更改为 ACTED:IN 并使用 DIRECTED 更改存在,如下所示:

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(d:Person)
WHERE exists((d)-[:DIRECTED]->(m))
RETURN p.name, d.name, m.title

这个结果: 正确的结果

我们可以看到没有像演员“汤姆汉克斯”、导演“汤姆汉克斯”这样的重复信息。

我的问题是,为什么 Neo4j 的行为如此微小的变化?

标签: neo4jcypher

解决方案


这与遍历单个模式匹配时的某种唯一性行为有关。

Cypher 使用称为 RELATIONSHIP_PATH 的唯一性,这意味着对于每条路径,关系必须是唯一的——每条路径只能遍历一次。

这样做有多种原因,最值得注意的是它隐含地防止了可变长度遍历的无限循环,因为无限循环要求您能够一遍又一遍地遍历相同的关系。

在第一个查询中,匹配是:

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(d:Person)

在这种情况下,同一节点可能与同一电影节点p具有 :ACTED_IN 和 :DIRECTED 关系。m这两种关系都将被遍历一次,没有问题,所以pd可能是同一个节点,所以你会看到同一个人的名字出现在结果中pd

在第二个查询中,匹配是:

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(d:Person)

在电影图中,对于一个在电影中表演的演员,这对节点之间只有一个 :ACTED_IN 关系,不会超过 1。

正因为如此,不可能d成为与 相同的节点p。:ACTED_IN 关系会从 person 节点遍历一次到 movie 节点,不能再次从 movie 节点遍历回 person 节点。

请注意,此限制仅对整个 MATCH 或 OPTIONAL MATCH 有效。如果您将单个 MATCH 分解为多个,如下所示:

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
MATCH (m)<-[:ACTED_IN]-(d:Person)
...

然后您将在结果中看到p与 相同节点的条目d。由于这里有两个 MATCH 模式,因此对模式之间遍历的关系没有限制。


推荐阅读