为什么单个Neo4j关系在Cypher查询结果中显示两次?

时间:2018-08-10 14:48:45

标签: neo4j cypher

让我们考虑一个有向关系的平凡图:

CREATE 
  (`0` :Car {value:"Ford"})
, (`1` :Car {value:"Subaru"})
, (`0`)-[:`DOCUMENT` {value:"DOC-1"}]->(`1`);

以下查询MATCH (n1:Car)-[r:DOCUMENT]-(n2:Car) RETURN *返回:

╒══════════════════╤══════════════════╤═════════════════╕
│"n1"              │"n2"              │"r"              │
╞══════════════════╪══════════════════╪═════════════════╡
│{"value":"Subaru"}│{"value":"Ford"}  │{"value":"DOC-1"}│
├──────────────────┼──────────────────┼─────────────────┤
│{"value":"Ford"}  │{"value":"Subaru"}│{"value":"DOC-1"}│
└──────────────────┴──────────────────┴─────────────────┘

该图仅定义了Ford->Subaru关系,为什么有两个关系?
如何解释颠倒的语句(第1行;在CREATE中未指定)?

注意:这是我先前提出的对mozilla developers的追问。我解决了我的问题,但是我不相信我的答案是最好的解决方案。

1 个答案:

答案 0 :(得分:1)

您的MATCH语句此处未指定方向,因此有两种可能会与模式匹配的路径(请记住,路径中节点的顺序很重要,并将路径彼此区分开),因此有两个答案。

如果您指定关系的方向,则会发现只有一条可能的路径可以匹配:

MATCH (n1:Car)-[r:DOCUMENT]->(n2:Car) 
RETURN *

关于为什么我们在省略方向时会返回两条路径的问题,请记住,路径是顺序敏感的:具有相同元素但具有不同元素顺序的两条路径是不同的路径。

为帮助您更好地理解这一点,请考虑以下两个查询:

# Query 1
MATCH (n1:Car)-[r:DOCUMENT]-(n2:Car) 
WHERE n1.value = 'Ford'
RETURN *

╒══════════════════╤══════════════════╤═════════════════╕
│"n1"              │"n2"              │"r"              │
╞══════════════════╪══════════════════╪═════════════════╡
│{"value":"Ford"}  │{"value":"Subaru"}│{"value":"DOC-1"}│
└──────────────────┴──────────────────┴─────────────────┘

# Query 2
MATCH (n1:Car)-[r:DOCUMENT]-(n2:Car) 
WHERE n1.value = 'Subaru'
RETURN *

╒══════════════════╤══════════════════╤═════════════════╕
│"n1"              │"n2"              │"r"              │
╞══════════════════╪══════════════════╪═════════════════╡
│{"value":"Subaru"}│{"value":"Ford"}  │{"value":"DOC-1"}│
└──────────────────┴──────────────────┴─────────────────┘

从概念上讲(在没有索引的情况下,计划程序也使用),要获得以上每个结果,请从描述中的完全匹配结果开始,然后过滤出唯一符合条件的结果给定条件。

如果原始查询仅返回一行而不是两行,则上述结果将与原始无方向匹配查询不一致。


OP的其他信息

我需要花些时间才能缠好它,但是它确实可以这样工作,这里有一个piece of documentation来确认是设计使然:

  

当您的模式包含绑定关系,并且该关系模式未指定方向时,Cypher会尝试在两个方向上匹配该关系。

     

MATCH (a)-[r]-(b)
  WHERE id(r)= 0
  RETURN a,b

     

这将返回两个连接的节点,一次是起始节点,一次是终止节点。