带有 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 的计数是多少?如果有多行具有相同的 x1
和 x2
节点,那么您可能有一些计数 > 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
以下查询工作正常:
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
和 [=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