Da gruppieren Sie nach dem Dokument _id
Sie können die Felder, die Sie behalten möchten, einfach innerhalb der Gruppierung _id
platzieren . Dann können Sie mit $project
db.c.aggregate([
{ "$unwind": "$array_to_sort"},
{ "$sort": {"array_to_sort.b":1, "array_to_sort:a": 1}},
{ "$group": {
"_id": {
"_id": "$_id",
"unknown_field": "$unknown_field"
},
"Oarray_to_sort": { "$push":"$array_to_sort"}
}},
{ "$project": {
"_id": "$_id._id",
"unknown_field": "$_id.unknown_field",
"array_to_sort": "$Oarray_to_sort"
}}
]);
Der andere "Trick" darin besteht darin, einen temporären Namen für das Array in der Gruppierungsphase zu verwenden. Dies ist der Fall, wenn Sie $project
und den Namen ändern, erhalten Sie die Felder in der Reihenfolge, die in der Projektionsanweisung angegeben ist. Andernfalls wäre das Feld "array_to_sort" nicht das letzte Feld in der Reihenfolge, da es aus der vorherigen Stufe kopiert wird.
Das ist eine beabsichtigte Optimierung in $project
, aber wenn Sie die Bestellung möchten, können Sie es wie oben tun.
Für völlig unbekannte Strukturen gibt es die mapReduce-Methode:
db.c.mapReduce(
function () {
this["array_to_sort"].sort(function(a,b) {
return a.a - b.a || a.b - b.b;
});
emit( this._id, this );
},
function(){},
{ "out": { "inline": 1 } }
)
Das hat natürlich ein MapReduce-spezifisches Ausgabeformat und daher nicht genau das Dokument, das Sie hatten, aber alle Felder sind unter "values" enthalten:
{
"results" : [
{
"_id" : 0,
"value" : {
"_id" : 0,
"some_field" : "a",
"array_to_sort" : [
{
"a" : 1,
"b" : 0
},
{
"a" : 3,
"b" : 3
},
{
"a" : 3,
"b" : 4
}
]
}
}
],
}
Zukünftige Versionen (zum Zeitpunkt des Schreibens) ermöglichen Ihnen die Verwendung eines $$ROOT
Variable insgesamt, um das Dokument darzustellen:
db.c.aggregate([
{ "$project": {
"_id": "$$ROOT",
"array_to_sort": "$array_to_sort"
}},
{ "$unwind": "$array_to_sort"},
{ "$sort": {"array_to_sort.b":1, "array_to_sort:a": 1}},
{ "$group": {
"_id": "$_id",
"array_to_sort": { "$push":"$array_to_sort"}
}}
]);
Es macht also keinen Sinn, die letzte "Projekt" -Phase zu verwenden, da Sie die anderen Felder im Dokument nicht wirklich kennen. Aber sie werden alle (einschließlich des ursprünglichen Arrays und der Reihenfolge ) in der _id
enthalten sein Feld des Ergebnisdokuments.