是否可以针对节点度数减少/优化此查询?

时间:2015-08-05 09:11:13

标签: neo4j cypher

鉴于以下Cypher查询返回传入(入站)和传出(出站)连接,并将总和作为节点度:

START n = node(*)
RETURN n.name, length((n)-->()) AS efferent,
length((n)<--()) AS afferent,
length((n)-->()) + length((n)<--()) AS degree

是否可以减少查询,以便在度数列的求和中不重复两个length()函数?

1 个答案:

答案 0 :(得分:2)

您可以使用length在返回之前和之前分别解析和绑定两个WITH计算。然后,您可以在返回时对这些绑定值求和。

START n = node(*)
WITH n, length((n)-->()) AS efferent, length((n)<--()) AS afferent
RETURN n.name, efferent, afferent, efferent + afferent AS degree

如果你的Neo4j版本是&gt; 2.0,你可能想要使用MATCH (n)而不是START n = node(*),但这不是你要求的,所以我会这样做假设你知道自己在做什么。

修改

在Neo4j 1.x START是您开始查询的方式。从2.x开始,当START仍然存在时,MATCH是首选方式。如果你有Neo4j 2.x并且不知道为什么要使用START,那么你应该使用MATCH。这是对原因的简短解释。

您的查询是为了触摸整个图表而编写的。如果这是意图,START n = node(*)MATCH (n)之间没有太大差异。执行计划确实有所不同,但我不知道差异非常重要。

但是,如果您只想在图表的某个部分执行计算,并添加到您的起点模式中。为此,那将会有显着的差异。例如,如果您只想在具有:User标签

的节点上执行计算
START n = node(*)
WHERE n:User

仍会提取所有节点,然后应用过滤器来丢弃那些没有标签的节点,而

MATCH (n)
WHERE n:User

只会启动具有该标签的节点。

一般区别在于:WHERE是伴随STARTMATCHOPTIONAL MATCHWITH的附属条款。当它伴随STARTWITH时,通过修改操作但通过过滤结果不起作用;当它伴随MATCHOPTIONAL MATCH时,它会修改(尽可能经常)操作,因此不必过滤结果。不同之处在于喊叫&#34;每个人,如果你是我的孩子,不要走在路上#34;并且&#34;孩子们,不要进入道路&#34;。

有些情况下,WHERE未加入MATCH子句。一个例子是

MATCH n
WHERE n:Male OR n:Female

在这种情况下,所有节点都会上拉然后进行过滤,就像我们使用START而不是MATCH一样。

有时很容易知道WHERE子句中的哪些模式可以被引入来修改MATCH。您可以通过简单地重新排列查询来自行移入MATCH子句的模式就是这种情况。上面的第一个MATCH示例也可以表达

MATCH (n:User)

但是,对于第二个WHERE示例MATCH中的WHERE n:Male OR n:Female子句,无法执行此操作。

通过重新构造查询无法将WHERE模式移动到MATCH子句中,这不是查询计划程序无法在匹配操作中使用它的可靠指示。作为一种声明性语言,您最终必须信任查询规划器以明智地实现指令;信任,但请验证。12

STARTMATCH之间的另一个区别与索引有关。如果你使用遗留索引&#39;那么你需要使用START来访问这些索引。新的&#39; (我相信大约两年)标签索引的功能和效率不断提高,我们没有理由使用旧索引。我认为剩下的唯一原因可能是全文索引,为此仍然需要配置的传统lucene索引。随着时间的推移,此功能也将添加到标签索引中。可能在那时,START条款将完全从Cypher中删除 - 但这只是作者的推测。