鉴于以下Cypher查询返回传入(入站)和传出(出站)连接,并将总和作为节点度:
START n = node(*)
RETURN n.name, length((n)-->()) AS efferent,
length((n)<--()) AS afferent,
length((n)-->()) + length((n)<--()) AS degree
是否可以减少查询,以便在度数列的求和中不重复两个length()函数?
答案 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
是伴随START
,MATCH
,OPTIONAL MATCH
或WITH
的附属条款。当它伴随START
或WITH
时,通过修改操作但通过过滤结果不起作用;当它伴随MATCH
和OPTIONAL 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
子句中,这不是查询计划程序无法在匹配操作中使用它的可靠指示。作为一种声明性语言,您最终必须信任查询规划器以明智地实现指令;信任,但请验证。1,2
START
和MATCH
之间的另一个区别与索引有关。如果你使用遗留索引&#39;那么你需要使用START
来访问这些索引。新的&#39; (我相信大约两年)标签索引的功能和效率不断提高,我们没有理由使用旧索引。我认为剩下的唯一原因可能是全文索引,为此仍然需要配置的传统lucene索引。随着时间的推移,此功能也将添加到标签索引中。可能在那时,START
条款将完全从Cypher中删除 - 但这只是作者的推测。