Aangezien u zich groepeert op het document _id
u kunt eenvoudig de velden die u wilt behouden in de groep plaatsen _id
. Vervolgens kun je opnieuw vormen met behulp van $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"
}}
]);
De andere "truc" daarin is het gebruik van een tijdelijke naam voor de array in de groeperingsfase. Dit is het geval wanneer u $project
en de naam wijzigt, krijgt u de velden in de volgorde die is opgegeven in de projectieverklaring. Als u dat niet deed, zou het veld "array_to_sort" niet het laatste veld in de volgorde zijn, omdat het is gekopieerd uit de vorige fase.
Dat is een beoogde optimalisatie in $project
, maar als u de bestelling wilt, kunt u dit doen zoals hierboven.
Voor volledig onbekende structuren is er de mapReduce-manier om dingen te doen:
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 } }
)
Dat heeft natuurlijk een uitvoerformaat dat specifiek is voor mapReduce en daarom niet precies het document dat u had, maar alle velden staan onder "waarden":
{
"results" : [
{
"_id" : 0,
"value" : {
"_id" : 0,
"some_field" : "a",
"array_to_sort" : [
{
"a" : 1,
"b" : 0
},
{
"a" : 3,
"b" : 3
},
{
"a" : 3,
"b" : 4
}
]
}
}
],
}
Toekomstige releases (op het moment van schrijven) stellen je in staat om een $$ROOT
. te gebruiken variabele in totaal om het document weer te geven:
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"}
}}
]);
Het heeft dus geen zin om de laatste "project"-fase te gebruiken, omdat u de andere velden in het document niet echt kent. Maar ze zullen allemaal worden opgenomen (inclusief de originele array en volgorde ) binnen de _id
veld van het resultaatdocument.