接受的答案帮助了我,但我花了一段时间才理解它是如何工作的,所以我想我会解释我的方法来帮助别人。特别是在您的情况下,我认为我的回答会有所帮助
理想情况下,这适用于较小的数据集
首先将数据按天分组,然后将数组中的所有天附加到每一天:
{
"$sort": {
"Date": -1
}
},
{
"$group": {
"_id": {
"Day": "$Date",
"Temperature": "$Temperature"
},
"Previous Values": {
"$push": {
"Date": "$Date",
"Temperature": "$Temperature"
}
}
}
这将为您留下如下所示的记录(将正确排序):
{"_id.Day": "2017-02-01",
"Temperature": 40,
"Previous Values": [
{"Day": "2017-03-01", "Temperature": 20},
{"Day": "2017-02-11", "Temperature": 22},
{"Day": "2017-01-18", "Temperature": 03},
...
]},
现在每一天都附加了所有天,我们需要从 Previous Values 数组中删除比 this _id.Day 字段更新的项目,因为移动平均线是向后看的:
{
"$project": {
"_id": 0,
"Date": "$_id.Date",
"Temperature": "$_id.Temperature",
"Previous Values": 1
}
},
{
"$project": {
"_id": 0,
"Date": 1,
"Temperature": 1,
"Previous Values": {
"$filter": {
"input": "$Previous Values",
"as": "pv",
"cond": {
"$lte": ["$$pv.Date", "$Date"]
}
}
}
}
},
Previous Values 数组中的每一项将仅包含小于或等于每条记录日期的日期:
{"Day": "2017-02-01",
"Temperature": 40,
"Previous Values": [
{"Day": "2017-01-31", "Temperature": 33},
{"Day": "2017-01-30", "Temperature": 36},
{"Day": "2017-01-29", "Temperature": 33},
{"Day": "2017-01-28", "Temperature": 32},
...
]}
现在我们可以选择我们的平均窗口大小,因为数据是按天计算的,对于一周我们将获取数组的前 7 条记录;每月,30;或 3 个月一次,90 天:
{
"$project": {
"_id": 0,
"Date": 1,
"Temperature": 1,
"Previous Values": {
"$slice": ["$Previous Values", 0, 90]
}
}
},
为了平均以前的温度,我们展开以前的值数组,然后按日期字段分组。展开操作是这样的:
{"Day": "2017-02-01",
"Temperature": 40,
"Previous Values": {
"Day": "2017-01-31",
"Temperature": 33}
},
{"Day": "2017-02-01",
"Temperature": 40,
"Previous Values": {
"Day": "2017-01-30",
"Temperature": 36}
},
{"Day": "2017-02-01",
"Temperature": 40,
"Previous Values": {
"Day": "2017-01-29",
"Temperature": 33}
},
...
看到 Day 字段是相同的,但我们现在从 Previous Values 数组中获得了每个先前日期的文档。 现在我们可以按天分组,然后平均 Previous Values.Temperature 以获得移动平均值:
{"$group": {
"_id": {
"Day": "$Date",
"Temperature": "$Temperature"
},
"3 Month Moving Average": {
"$avg": "$Previous Values.Temperature"
}
}
}
就是这样!我知道将每条记录连接到每条记录并不理想,但这适用于较小的数据集