如何在Neo4j中使用Cypher实现7天滑动窗口平均值计算
Cypher 7天滑动窗口平均值实现方案
前提假设
- day节点包含可排序的日期属性
date,推荐使用Neo4j原生Date类型存储,也可使用格式统一的可排序字符串、时间戳数值替代 - 业务节点thing的指标属性名为
metric,关联关系符合(thing)-[]->(day)的匹配规则
实现代码(无日期缺失场景)
如果你的day节点是连续无缺失的,每天都有对应的day节点,可以直接按排序后的窗口取7个节点计算:
// 匹配所有day节点按日期升序排序,生成有序集合 MATCH (d:day) WITH d ORDER BY d.date ASC WITH collect(d) AS allDays // 遍历每个day节点定位窗口范围 UNWIND range(0, size(allDays)-1) AS idx WITH allDays[idx] AS currentDay, // 取当前及之前共7个day节点,不足7天的取到首个节点为止 allDays[CASE WHEN idx-6 <0 THEN 0 ELSE idx-6 END .. idx+1] AS windowDays // 匹配窗口内所有day关联的thing节点 MATCH (t:thing)-[]->(d:day) WHERE d IN windowDays // 计算窗口平均值 WITH currentDay, avg(t.metric) AS sevenDayAvg // 按要求格式返回结果 RETURN currentDay AS day, sevenDayAvg ORDER BY currentDay.date ASC
实现代码(可能存在日期缺失场景)
如果存在部分日期没有对应day节点的情况,按自然日范围滑动计算更准确:
MATCH (currentDay:day) // 筛选窗口范围:当前day日期往前推6天到当前日期的闭区间 MATCH (t:thing)-[]->(windowDay:day) WHERE windowDay.date >= date(currentDay.date) - duration({days:6}) AND windowDay.date <= currentDay.date WITH currentDay, avg(t.metric) AS sevenDayAvg RETURN currentDay AS day, sevenDayAvg ORDER BY currentDay.date ASC
注意:如果你的day节点的日期属性是时间戳或者字符串格式,需要对应修改WHERE条件里的日期计算逻辑,比如毫秒级时间戳要减6*86400*1000
内容的提问来源于stack exchange,提问作者Bonnie Shen
相关产品推荐
相关产品推荐

