虽然这可能不是完整的答案,但信息太多,无法发表评论。不过,这应该会提供一些有用的见解。
我认为这是一个错误。以下是样本数据中应给出相同结果的一些变化。它们都应该通过给定的数据(通过返回任何内容)
MATCH (a:A)-[r]-(b:B) WHERE (b)-[r]-(a) RETURN *
-> 失败
remove r
MATCH (a:A)--(b:B) WHERE (b)--(a) RETURN *
-> 通过
MATCH (a:A)-[r]-(b:B) WHERE (b)--(a) RETURN *
-> 通过
添加方向
MATCH (a:A)-[r]-(b:B) WHERE (b)<-[r]-(a) RETURN *
-> 通过
相反的顺序
MATCH (a:A)-[r]-(b:B) WHERE (a)-[r]-(b) RETURN *
-> 通过
并且,从失败的测试的概况来看
+---------------------+----------------+------+---------+-----------+--------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+---------------------+----------------+------+---------+-----------+--------------+
| +ProduceResults | 1 | 0 | 0 | a | a |
| | +----------------+------+---------+-----------+--------------+
| +SemiApply | 1 | 0 | 0 | a, b, r | |
| |\ +----------------+------+---------+-----------+--------------+
| | +ProjectEndpoints | 1 | 0 | 0 | a, b, r | r, b, a |
| | | +----------------+------+---------+-----------+--------------+
| | +Argument | 2 | 1 | 0 | a, b, r | |
| | +----------------+------+---------+-----------+--------------+
| +Filter | 2 | 1 | 1 | a, b, r | a:A |
| | +----------------+------+---------+-----------+--------------+
| +Expand(All) | 2 | 1 | 3 | a, r -- b | (b)-[r:]-(a) |
| | +----------------+------+---------+-----------+--------------+
| +NodeByLabelScan | 2 | 2 | 3 | b | :B |
+---------------------+----------------+------+---------+-----------+--------------+
和等效的通过测试(相反顺序)
+---------------------+----------------+------+---------+-----------+--------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+---------------------+----------------+------+---------+-----------+--------------+
| +ProduceResults | 1 | 1 | 0 | a | a |
| | +----------------+------+---------+-----------+--------------+
| +SemiApply | 1 | 1 | 0 | a, b, r | |
| |\ +----------------+------+---------+-----------+--------------+
| | +ProjectEndpoints | 1 | 0 | 0 | a, b, r | r, a, b |
| | | +----------------+------+---------+-----------+--------------+
| | +Argument | 2 | 1 | 0 | a, b, r | |
| | +----------------+------+---------+-----------+--------------+
| +Filter | 2 | 1 | 1 | a, b, r | a:A |
| | +----------------+------+---------+-----------+--------------+
| +Expand(All) | 2 | 1 | 3 | a, r -- b | (b)-[r:]-(a) |
| | +----------------+------+---------+-----------+--------------+
| +NodeByLabelScan | 2 | 2 | 3 | b | :B |
+---------------------+----------------+------+---------+-----------+--------------+
请注意每个步骤 1 之后的行数。同一个计划不应该产生不同的结果。我可以推测这是一个与图修剪快捷方式相关的错误(即,一旦 Neo4j 沿一个方向遍历一条边,它就不会在同一场比赛中遍历回同一边。这是一个反循环故障安全/性能特征)因此,理论上,在将 where 部分与 match 部分的顺序颠倒后,Neo4j 必须遍历修剪过的边来验证关系。如果方向相同,则自动通过。如果 Neo4j 尝试反向执行相同的检查,则会失败,因为该边缘已被修剪。 (但这只是理论。失败的验证在技术上是相反的 r 验证)