Puisque vous regroupez sur le document _id
vous pouvez simplement placer les champs que vous souhaitez conserver dans le groupement _id
. Ensuite, vous pouvez reformer en utilisant $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"
}}
]);
L'autre "astuce" consiste à utiliser un nom temporaire pour le tableau lors de l'étape de regroupement. C'est le cas lorsque vous $project
et modifiez le nom, vous obtenez les champs dans l'ordre spécifié dans l'instruction de projection. Si vous ne l'avez pas fait, le champ "array_to_sort" ne serait pas le dernier champ de l'ordre, car il est copié de l'étape précédente.
C'est une optimisation prévue dans $project
, mais si vous voulez la commande, vous pouvez le faire comme ci-dessus.
Pour les structures totalement inconnues, il existe la méthode mapReduce :
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 } }
)
Bien sûr, cela a un format de sortie spécifique à mapReduce et donc pas exactement le document que vous aviez, mais tous les champs sont contenus sous "values" :
{
"results" : [
{
"_id" : 0,
"value" : {
"_id" : 0,
"some_field" : "a",
"array_to_sort" : [
{
"a" : 1,
"b" : 0
},
{
"a" : 3,
"b" : 3
},
{
"a" : 3,
"b" : 4
}
]
}
}
],
}
Les futures versions (au moment de l'écriture) vous permettent d'utiliser un $$ROOT
variable en agrégat pour représenter le document :
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"}
}}
]);
Il est donc inutile d'utiliser l'étape finale du "projet" car vous ne connaissez pas réellement les autres champs du document. Mais ils seront tous contenus (y compris le tableau et l'ordre d'origine) dans le _id
champ du document résultat.