带有 WITH 子句的奇怪 Neo4j Cypher 聚合器行为

Strange Neo4j Cypher Aggregator behaviour with WITH Clause

以下查询工作正常:

Match (x1:A) with x1 
optional Match (x1)-[:A_B]-(x2:B) 
with x1 ,count(x2) as x3 
where x1.foo= 'bar' and (x3 = 1) 
return DISTINCT x1 as A 
SKIP 0 
LIMIT 10

但是这个查询给出了错误的输出

Match (x1:A) with x1 
optional Match (x1)-[:A_B]-(x2:B) 
with x1 ,x2, count(x2) as x3 
where x1.foo= 'bar' and (x3 = 1) 
return DISTINCT x1 as A 
SKIP 0 
LIMIT 10

没有错,这只是对在 Cypher 中聚合时隐式分组键的工作方式的误解。

聚合时,非聚合术语成为分组键,这是您要聚合的内容的上下文。

主要区别在于聚合时的 WITH 子句。在第一个查询中,您有:

with x1 ,count(x2) as x3 

您对 count(x2) 的汇总是根据 x1。所以每个不同的 x1 节点,关联的 x2 节点的计数。

在您的第二个查询中,变量不同,因此分组键也不同:

with x1 ,x2, count(x2) as x3 

对于 x1 和 x2,特定 x2 的计数是多少?如果有多行具有相同的 x1x2 节点,那么您可能有一些计数 > 1。但是如果特定的 x1 和 [=16= 只有一行] 节点,则计数为 1.

编辑

如果你想得到每个 x1 的 x2 的计数,然后继续使用 x2 节点,那么你需要在计数(x2)的同时收集(x2)(因为它是一个聚合项,它不是分组键的一部分)。然后您可以将列表展开回行。

您的查询实际上并没有使用 x2 节点,所以我们真的不需要对它们做任何事情,但我还是会展示该技术:

Match (x1:A) 
with x1 
optional Match (x1)-[:A_B]-(x2:B) 
with x1 , collect(x2) as nodes, count(x2) as x3 
where x1.foo= 'bar' and (x3 = 1) 
UNWIND nodes as x2
return DISTINCT x1 as A 
SKIP 0 
LIMIT 10