Das tut, was Sie brauchen. Ich habe die Zeiten in den Daten normalisiert, sodass sie gruppiert werden (Sie könnten so etwas tun). Die Idee ist $group
und drücken Sie die time
's und total
's in separate Arrays. Dann $unwind
die time
Array, und Sie haben eine Kopie der totals
erstellt Array für jede time
dokumentieren. Sie können dann die runningTotal
berechnen (oder so etwas wie der gleitende Durchschnitt) aus dem Array, das alle Daten für verschiedene Zeiten enthält. Der von $unwind
generierte 'Index' ist der Array-Index für total
entsprechend dieser time
. Es ist wichtig, $sort
zu verwenden vor $unwind
da dies sicherstellt, dass die Arrays in der richtigen Reihenfolge sind.
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 ] } ] } },
}
},
]
);
Ich habe etwas Ähnliches für eine Sammlung mit ~80.000 Dokumenten verwendet, die sich zu 63 Ergebnissen summieren. Ich bin mir nicht sicher, wie gut es bei größeren Sammlungen funktionieren wird, aber ich habe festgestellt, dass die Durchführung von Transformationen (Projektionen, Array-Manipulationen) an aggregierten Daten keine großen Leistungskosten zu verursachen scheint, sobald die Daten auf eine überschaubare Größe reduziert wurden. P>