Poiché stai raggruppando sul documento _id
puoi semplicemente inserire i campi che desideri mantenere all'interno del raggruppamento _id
. Quindi puoi riformattare utilizzando $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'altro "trucco" è usare un nome temporaneo per l'array nella fase di raggruppamento. È così quando $project
e cambia il nome, ottieni i campi nell'ordine specificato nella dichiarazione di proiezione. In caso contrario, il campo "array_to_sort" non sarebbe l'ultimo campo nell'ordine, poiché è stato copiato dalla fase precedente.
Questa è un'ottimizzazione prevista in $project
, ma se vuoi l'ordine puoi farlo come sopra.
Per strutture completamente sconosciute c'è il modo di fare 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 } }
)
Ovviamente ha un formato di output specifico per mapReduce e quindi non esattamente il documento che avevi, ma tutti i campi sono contenuti in "valori":
{
"results" : [
{
"_id" : 0,
"value" : {
"_id" : 0,
"some_field" : "a",
"array_to_sort" : [
{
"a" : 1,
"b" : 0
},
{
"a" : 3,
"b" : 3
},
{
"a" : 3,
"b" : 4
}
]
}
}
],
}
Le versioni future (al momento della scrittura) ti consentono di utilizzare un $$ROOT
variabile in aggregato per rappresentare il documento:
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"}
}}
]);
Quindi non ha senso utilizzare la fase finale del "progetto" poiché in realtà non conosci gli altri campi del documento. Ma saranno tutti contenuti (incluso l'array e l'ordine originali) all'interno del _id
campo del documento risultato.