neo4j - 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 的行为如此微小的变化?
解决方案
这与遍历单个模式匹配时的某种唯一性行为有关。
Cypher 使用称为 RELATIONSHIP_PATH 的唯一性,这意味着对于每条路径,关系必须是唯一的——每条路径只能遍历一次。
这样做有多种原因,最值得注意的是它隐含地防止了可变长度遍历的无限循环,因为无限循环要求您能够一遍又一遍地遍历相同的关系。
在第一个查询中,匹配是:
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(d:Person)
在这种情况下,同一节点可能与同一电影节点p
具有 :ACTED_IN 和 :DIRECTED 关系。m
这两种关系都将被遍历一次,没有问题,所以p
和d
可能是同一个节点,所以你会看到同一个人的名字出现在结果中p
。d
在第二个查询中,匹配是:
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 模式,因此对模式之间遍历的关系没有限制。
推荐阅读
- typescript - 如何在连接打开一次的打字稿中建立mongodb NodeJS驱动程序连接
- javascript - 无法在文本框中显示当前日期
- mysql - Django:酒店预订数据库 start_date 和 end_date
- sql - 如果 IN 子句中的空表,Postgresql 查询会变慢
- python - 你可以在 python 中为 threading.local() 分配一个列表吗?
- python - 如何将多个标题 Excel 文档转换为 Pandas
- javascript - MongoDB 更新很多文档 Schema.Types.Mixed
- bash - 用于选择子目录中的 .c 文件的 bash 脚本
- elasticsearch - 将文本字段映射到 Elasticsearch 中的整数字段
- python - 我正在尝试为我的项目安装所有必需的模块