在Neo4j中对密码查询的误解

时间:2018-04-30 07:48:40

标签: neo4j cypher

请看下面的示例图(来自Neo4j参考):

image

其他查询是:

MATCH (david { name: 'David' })--(otherPerson)-->()
WITH otherPerson, count(*) AS foaf
WHERE foaf > 1
RETURN otherPerson.name

结果是:

"Anders"

我无法理解为什么这个结果会回归。首先,
这是什么意思:

MATCH (david { name: 'David' })--(otherPerson)-->()
WITH otherPerson, count(*) AS foaf

具体而言,Bossman还有(如Anders)两个传出边并连接到David

有人能解释一下这个查询的语义吗?

1 个答案:

答案 0 :(得分:3)

因此,您注意到有两个节点看起来符合您描述的模式。安德斯和博斯曼都与大卫有联系,两人都有两个外向关系。

您缺少的是使用Cypher模式relationships are unique for the pattern,它们将不会被重用(这实际上非常有用,例如,当存在循环时,它会在使用可变长度关系时阻止无限循环)。

所以在这个MATCH模式中:

MATCH (david { name: 'David' })--(otherPerson)-->()

以前从大卫到Bossman的关系(:BLOCKS关系)不会在模式中重复使用(特别是(otherPerson)-->()部分),所以你只能得到一个结果行,而对于你会得到的安德斯2.你的WHERE子句然后排除了Bossman的匹配,因为foaf的数量是1。

您可以更改此查询以获得所需结果的一种方法是检查WHERE子句中的关系度,而不是MATCH模式中的关系度。这也更有效,因为检查关系度不必执行扩展操作,关系度数据在节点本身上。

MATCH ({ name: 'David' })--(otherPerson)
WHERE size((otherPerson)-->()) > 1
RETURN otherPerson.name

(在匹配中使用节点标签也是一个好主意,至少对于你想要的起始节点。索引(如果存在)只会在你在匹配中明确同时使用label和indexed属性时使用它如果省略标签,或使用不属于索引的标签,则无效。