これはあなたが必要とすることをします。データの時間を正規化して、グループ化するようにしました(このようなことを行うことができます)。アイデアは$group
time
をプッシュします とtotal
を別々の配列に。次に、$unwind
time
配列、およびtotals
のコピーを作成しました 各time
の配列 資料。次に、runningTotal
を計算できます (または移動平均のようなもの)異なる時間のすべてのデータを含む配列から。 $unwind
によって生成された「インデックス」 total
の配列インデックスです そのtime
に対応 。 $sort
を実行することが重要です $unwind
の前 これにより、アレイが正しい順序になっていることが保証されます。
db.temp.aggregate(
[
{
'$group': {
'_id': '$time',
'total': { '$sum': '$value' }
}
},
{
'$sort': {
'_id': 1
}
},
{
'$group': {
'_id': 0,
'time': { '$push': '$_id' },
'totals': { '$push': '$total' }
}
},
{
'$unwind': {
'path' : '$time',
'includeArrayIndex' : 'index'
}
},
{
'$project': {
'_id': 0,
'time': { '$dateToString': { 'format': '%Y-%m-%d', 'date': '$time' } },
'total': { '$arrayElemAt': [ '$totals', '$index' ] },
'runningTotal': { '$sum': { '$slice': [ '$totals', { '$add': [ '$index', 1 ] } ] } },
}
},
]
);
私は、最大80 000のドキュメントを含むコレクションで同様のものを使用し、63の結果に集約しました。大規模なコレクションでどれだけうまく機能するかはわかりませんが、データが管理可能なサイズに縮小された後は、集合データで変換(射影、配列操作)を実行してもパフォーマンスコストが高くないように思われることがわかりました。