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

带有with子句的Neo4j Cypher聚合器奇怪行为,neo4j,cypher,Neo4j,Cypher,以下查询工作正常: 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

以下查询工作正常:

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的计数是多少?如果有多行具有相同的
x1
x2
节点,则可能有一些计数>1。但是,如果对于特定的
x1
x2
节点只有一行,则计数将为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

这并不是错误的,这只是对在Cypher中聚合时隐式分组键如何工作的误解

聚合时,非聚合项将成为分组键,这是您正在聚合的内容的上下文

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

with x1 ,count(x2) as x3 
您的
count(x2)
的聚合是根据
x1
。因此,对于每个不同的x1节点,关联的x2节点的计数

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

with x1 ,x2, count(x2) as x3 
根据x1和x2,特定x2的计数是多少?如果有多行具有相同的
x1
x2
节点,则可能有一些计数>1。但是,如果对于特定的
x1
x2
节点只有一行,则计数将为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

那么我们如何编写查询,在那里我们可以对x2执行一些操作?对于这一点,我们需要使用WITHUpdated传递x2,其中包含有关如何执行此操作的信息。那么我们如何编写查询,在其中可以对x2执行一些操作?至于这一点,我们需要通过x2使用更新的信息如何做到这一点。