Es ist wichtig zu verstehen, dass die Operationen im Argument von Aggregat() eine Pipeline bilden . Das bedeutet, dass die Eingabe für jedes Element der Pipeline der Strom von Dokumenten ist, der vom vorherigen Element in der Pipeline erzeugt wurde.
In Ihrem Beispiel erstellt Ihre erste Abfrage eine Pipeline von Dokumenten, die wie folgt aussehen:
{
"_id" : 2,
"avg_score" : 5.5
},
{
"_id" : 1,
"avg_score" : 4
}
Das bedeutet, dass das zweite Element der Pipeline eine Reihe von Dokumenten sieht, bei denen die einzigen Schlüssel "_id" und "avg_score" sind. Die Schlüssel "category_id" und "score" existieren nicht mehr in diesem Dokumentenstrom.
Wenn Sie diesen Stream weiter aggregieren möchten, müssen Sie mithilfe der Schlüssel aggregieren, die in dieser Phase der Pipeline angezeigt werden. Da Sie die Durchschnittswerte mitteln möchten, müssen Sie einen einzigen konstanten Wert für das Feld _id eingeben, damit alle Eingabedokumente in einem einzigen Ergebnis gruppiert werden.
Der folgende Code erzeugt das richtige Ergebnis:
db.questions.aggregate(
{ $group : {
_id : "$category_id",
avg_score : { $avg : "$score" },
}
},
{ $group : {
_id : "all",
avg_score : { $avg : "$avg_score" },
}
}
);
Wenn es ausgeführt wird, erzeugt es die folgende Ausgabe:
{
"result" : [
{
"_id" : "all",
"avg_score" : 4.75
}
],
"ok" : 1
}