为何该Neo4j查询未匹配到预期的David自关联结果?
问题:为什么Neo4j查询未返回预期的自环路径结果?
初始化数据库数据
首先在空Neo4j数据库中执行以下创建语句:
CREATE (an:Person { name: "Anders" }) CREATE (ces:Person { name: "Caesar" }) CREATE (boss:Person { name: "Bossman" }) CREATE (geor:Person { name: "George" }) CREATE (dav:Person { name: "David" }) CREATE (an)-[:BLOCKS]->(ces) CREATE (an)-[:KNOWS]->(boss) CREATE (an)<-[:KNOWS]-(dav) CREATE (ces)-[:KNOWS]->(geor) CREATE (boss)-[:KNOWS]->(geor) CREATE (boss)-[:BLOCKS]->(dav) CREATE (dav)-[:BLOCKS]->(dav)
执行查询
随后运行以下Cypher查询:
MATCH (x { name: "David" })--(y)-->(z) RETURN x.name, y.name, z.name
查询结果
得到的返回结果如下:
| x.name | y.name | z.name |
|---|---|---|
| "David" | "David" | "Anders" |
| "David" | "Bossman" | "George" |
| "David" | "Anders" | "Bossman" |
| "David" | "Anders" | "Caesar" |
疑问
结果第一行证明查询允许重复节点(x和y都是David),但为什么预期的以下行没有被返回?
| x.name | y.name | z.name |
|---|---|---|
| "David" | "David" | "David" |
原因解释
问题出在Cypher对路径模式匹配的默认规则上:
- 你的查询模式
(x)--(y)-->(z)是一个连续路径匹配,表示匹配一条从x到z的两步路径,路径中的每个关系实例只能被使用一次。 - 预期结果对应的路径是:David(x)通过自环关系连接到David(y),再通过同一个自环关系连接到David(z)。但你的数据库中David只有一个自环关系(
dav-[:BLOCKS]->dav),Cypher不允许在同一条路径中重复使用同一个关系实例。 - 而结果第一行
David, David, Anders是合法的,因为它用到了两个完全不同的关系:David的自环关系(x到y),以及David指向Anders的KNOWS关系(y到z),这两个是独立的关系实例,所以能被匹配到。
如何得到预期结果
如果想要返回David, David, David这一行,需要把连续路径模式拆分为两个独立的匹配模式,这样就允许重复使用同一个关系实例:
MATCH (x { name: "David" })--(y), (y)-->(z) RETURN x.name, y.name, z.name
执行这个查询就能得到你预期的结果行。
内容的提问来源于stack exchange,提问作者AFatNiBBa
相关产品推荐
相关产品推荐

