Ini melakukan apa yang Anda butuhkan. Saya telah menormalkan waktu dalam data sehingga mereka dikelompokkan bersama (Anda dapat melakukan sesuatu seperti ini). Idenya adalah untuk $group
dan tekan time
's dan totals
's ke dalam array yang terpisah. Kemudian $unwind
time
array, dan Anda telah membuat salinan totals
larik untuk setiap time
dokumen. Anda kemudian dapat menghitung runningTotal
(atau sesuatu seperti rata-rata bergulir) dari larik yang berisi semua data untuk waktu yang berbeda. 'Indeks' yang dihasilkan oleh $unwind
adalah indeks array untuk totals
sesuai dengan time
itu . Penting untuk $sort
sebelum $unwind
ing karena ini memastikan array berada dalam urutan yang benar.
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 ] } ] } },
}
},
]
);
Saya telah menggunakan sesuatu yang serupa pada koleksi dengan ~80 000 dokumen, menggabungkan ke 63 hasil. Saya tidak yakin seberapa baik itu akan bekerja pada koleksi yang lebih besar, tetapi saya telah menemukan bahwa melakukan transformasi (proyeksi, manipulasi array) pada data agregat tampaknya tidak memiliki biaya kinerja yang besar setelah data dikurangi menjadi ukuran yang dapat dikelola.