Neo4j 似乎故意省略了循环,因此查询如下:
MATCH (n1)-[:R]->(n2)<-[:R]-(n1)
RETURN n1, n2;
除非存在两个类型关系,否则始终不返回任何内容R
之间n1
and n2
(这绝对是可能的,而且是一个糟糕的黑客)。
但我有一个场景,这个循环可能会发生并且是期望的:
MATCH (n1)-[:R]->(n2)<-[:R]-(n3)
RETURN n1, n2, n3;
在这个查询中,n1
and n3
可能是相同的节点或不同的节点,这一切都取决于数据(两者都是有效的)。实现此目的的一种方法如下:
MATCH (n1)-[:R]->(n2)
MATCH (n2)<-[:R]-(n3)
RETURN n1, n2, n3;
最后一个查询将包括所有路径,甚至循环,这完全没问题。但我的情况比这更复杂:
MATCH (n0)
OPTIONAL MATCH (n0)-[:R0]->(n1)-[:R]->(n2)<-[:R]-(n3)
RETURN n0, n1, n2, n3;
正如我们之前所见,此查询中省略了循环,因此我们必须将其分解为两个OPTIONAL MATCH
es:
MATCH (n0)
OPTIONAL MATCH (n0)-[:R0]->(n1)-[:R]->(n2)
OPTIONAL MATCH (n2)<-[:R]-(n3)
RETURN n0, n1, n2, n3;
但这和以前不一样(如果另一个有效的话)。这里是第二个OPTIONAL MATCH
当第一个路径返回时,可能不会返回任何路径。换句话说,两人OPTIONAL MATCH
es 是独立的。
所以我的问题是:如何实现以下查询并获取结果中的周期?
MATCH (n0)
OPTIONAL MATCH (n0)-[:R0]->(n1)-[:R]->(n2)<-[:R]-(n3)
RETURN n0, n1, n2, n3;
我希望它不会太混乱!
Why two OPTIONAL MATCH
es 不是答案
考虑以下节点和关系:
CREATE (n0:S)-[:R]->(n1:R)<-[:R]-(n2:E)-[:R]->(n3:R:L);
CREATE (n0:S)-[:R]->(n1:R:L)<-[:R]-(n2:E);
CREATE (n0:S)-[:R]->(n1:R)<-[:R]-(n2:E);
在上面的示例中,以下是标签的含义(以便您能够理解问题):
-
:S
起始节点
-
:R
修订
-
:E
entity
-
:L
最新版本与最新版本相同
在此示例中,每条数据记录都表示为:E
+:R
当记录更新时,一个新的:R
被添加到其中。数据的当前状态被标记:L
这样我们就可以找到最新的版本。
现在,在给定的三个示例中,最后一个是无效数据,因为它没有任何数据:L
。第一个有两次修订,第二个有一次。
请求的查询应该:
- Return
:S
不管
- 返回所有实体及其最新修订版(仅当它们具有最新修订版时)
- 没有最新修订的实体是没有意义的,根本不应该返回
如果 Neo4j 支持循环,此查询将返回请求的数据:
MATCH (n1:S)
OPTIONAL MATCH (n1)-[:R]->(n2:R)<-[:R]-(n3:E)-[:R]->(n4:R:L)
RETURN labels(n1), labels(n3), labels(n4);
The 预期成绩对于上面的查询是:
╒════════════╤════════════╤════════════╕
│"labels(n1)"│"labels(n3)"│"labels(n4)"│
╞════════════╪════════════╪════════════╡
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │null │null │
└────────────┴────────────┴────────────┘
But the 实际结果 are:
╒════════════╤════════════╤════════════╕
│"labels(n1)"│"labels(n3)"│"labels(n4)"│
╞════════════╪════════════╪════════════╡
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │null │null │
├────────────┼────────────┼────────────┤
│["S"] │null │null │
└────────────┴────────────┴────────────┘
正如您所看到的,第二条路径被缩短,因为它包含一个循环。现在如果我们使用这两个OPTIONAL MATCH
方法:
MATCH (n1:S)
OPTIONAL MATCH (n1)-[:R]->(n2:R)<-[:R]-(n3:E)
OPTIONAL MATCH (n3)-[:R]->(n4:R:L)
RETURN labels(n1), labels(n3), labels(n4);
结果将是:
╒════════════╤════════════╤════════════╕
│"labels(n1)"│"labels(n3)"│"labels(n4)"│
╞════════════╪════════════╪════════════╡
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │["E"] │null │
└────────────┴────────────┴────────────┘
虽然第二种情况已得到解决,但第三种情况现在是问题所在,因为这两个可选子句可以独立存在。
抱歉问了这么长的问题,我试着简短一点!