Cypher中无向路径的计数与去重问题咨询
解析Cypher无向路径的计数差异
嘿,我来帮你拆解这个Cypher无向路径计数的问题~先看你给出的两个查询和结果:
// 有向路径查询 MATCH path = (a)-[]->(b) RETURN count(path), count(distinct(path)) // 结果:count(path):1236951,count(distinct(path)):1236951
// 无向路径查询 MATCH path = (a)-[]-(b) RETURN count(path), count(distinct(path)) // 结果:count(path):2473901,count(distinct(path)):2473901
问题a:为什么无向场景下的count(path)并非完全是有向场景的两倍?
答案很简单:你的图里存在1条自环边(即某个节点自身指向自身的边,形如(n)-[]->(n))。
咱们来拆解计数逻辑:
- 对于普通的非自环有向边
(u)->(v)(u≠v):无向模式(a)-[]-(b)会匹配到两条独立路径:(u)-[]-(v)(对应原方向)和(v)-[]-(u)(对应反向),这部分的计数是有向边数的2倍。 - 对于自环边
(n)->(n):有向模式下只会匹配到1条路径;而无向模式下,因为起点和终点都是同一个节点,反向后还是同一条路径,所以只会被计数1次,而不是2次。
对应你的数据:
有向总边数是1236951,其中包含1条自环边,那么非自环有向边数是1236951-1=1236950。无向路径总数就是1236950*2 + 1=2473901,和你的查询结果完全吻合。
额外补充:为什么count(path)和count(distinct(path))相等?
不管是有向还是无向查询,Cypher匹配到的每条路径都是唯一的:
- 有向路径中,每条边对应唯一的
(a)->(b)路径,没有重复。 - 无向路径中,即使是反向的
(u)-[]-(v)和(v)-[]-(u),也被视为两条不同的路径(因为路径的起点和终点顺序不同),所以也没有重复的路径需要去重。因此两种查询的去重计数和原计数一致。
内容的提问来源于stack exchange,提问作者Scofflaw
相关产品推荐
相关产品推荐

