Neo4j Cypher Aggregate函数在WITH子句中的更改

时间:2018-08-28 10:17:10

标签: neo4j cypher aggregate-functions

我是Neo4j的新手,平均功能有问题。

我有一个关于银行帐户(节点)和它们之间的付款(关系)的测试数据库。

我想计算每对帐户之间(例如A&B之间,A&C之间,B&C之间,等等)的付款平均值,然后找到比平均值高出$ 50的付款。

我的代码如下:

MATCH (a)-[r:Payment]-(b)
WITH a, b, AVG(ToFloat(r.Amount)) AS Average, ToFloat(r.Amount) as Amount
WHERE Amount-Average>50
RETURN a, b, Amount-Average AS Difference

如果我仅在WITH子句中保留a和Average,这似乎可以正确计算平均值,但是如果我添加其他任何内容(r或r.Amount子句),则Average函数的输出将发生变化,并且仅返回与“金额”相同的值(因此,对于每个关系,它都会将“差异”计算为0)。

难道是我匹配节点和关系的方式没有正确找到每对帐户之间的关系,然后对它们进行平均,这会导致错误吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

这是执行聚合时Cypher隐式分组的结果。分组键(分组发生的上下文)是隐式的,由WITH或RETURN子句中存在的非聚合变量形成。

这就是为什么当您包含rr.amount时,输出会发生变化,因为您将针对相同的关系或相同的数量(单个平均值的平均值)计算平均值价值就是那个价值。)

由于您要基于平均值评估和过滤节点之间的所有金额,因此在获取平均值时应收集金额,然后对内容进行过滤/转换以供返回。

此外,您还希望对ab进行一些过滤,以确保您不返回镜像结果(除了{{1 }}和a交换),因此我们将对节点ID进行限制,以确保仅在单个方向上订购:

b

如果您希望每一行都有单独的结果,则可以在退回之前取消缠绕MATCH (a)-[r:Payment]-(b) WHERE id(a) < id(b) // ensure we don't get mirrored results WITH a, b, AVG(ToFloat(r.Amount)) AS Average, collect(ToFloat(r.Amount)) as Amounts WITH a, b, [amt in Amounts WHERE amt-Average > 50 | amt - Average] as Differences RETURN a, b, Differences 列表。