跳到主要内容

1 篇博文 含有标签「nebula graph」

查看所有标签

Nebula Graph 中的连续匹配

· 阅读需 2 分钟
1adybug
子虚伊人

先看两组 Cypher 语句:

MATCH p = (u:`user`)-[w:watched]->(m:`movie`)
WHERE w.rate > 4
RETURN count(p)
MATCH (u:`user`)-[w:watched]->(m:`movie`)
WHERE w.rate > 4
MATCH p = (u:`user`)-[w:watched]->(m:`movie`)
RETURN count(p)

通过运行结果可知两组语句的结果是一样的,可知连续匹配的作用域就是上一个匹配的结果。 uwm 是上一个匹配的结果,所以第二组语句中的 count(p) 与第一组语句中的 count(p) 是一样的。

如果我们把第二组语句改为:

MATCH (u:`user`)-[w:watched]->(m:`movie`)
WHERE w.rate > 4
MATCH p = (u:`user`)-[w2:watched]->(m:`movie`)
RETURN count(p)

那么此时,只有 um 是继承了上一次匹配的结果,w2 是重新匹配的结果,所以 count(p) 的结果就不一样了,也就是对于每一组 um 重新匹配了 w2 这条边,那么 count(p) 的结果必然是大于或者等于第一组语句的结果。

MATCH (u:`user`)-[w:watched]->(m:`movie`)
WHERE w.rate > 4
WITH u, m
MATCH p = (u:`user`)-[w:watched]->(m:`movie`)
RETURN count(p)

此时如果我们使用 WITH,那么 w 依然被丢失了,在第二次匹配中的 w 也相当于重新匹配的结果,所以 count(p) 的结果也是大于或者等于第一组语句的结果。

如果我们做以下改动也是错误的:

MATCH (u:`user`)-[w:watched]->(m:`movie`)
WHERE w.rate > 4
WITH u, m
MATCH p = (u:`user`)-[w:watched]->(m:`movie`)
WHERE w.rate > 4
RETURN count(p)

因为第一次匹配的结果并没有保证 um 之间的组合是独一无二的,也就是结果的列表中可能会存在系统的 um 组合,所以我们应该加一个语句:

MATCH (u:`user`)-[w:watched]->(m:`movie`)
WHERE w.rate > 4
WITH u, m, count(w) as c
MATCH p = (u:`user`)-[w:watched]->(m:`movie`)
WHERE w.rate > 4
RETURN count(p)

通过 count(w) 就可以让 um 之间的组合是独一无二的