Como você está agrupando no documento
_id
você pode simplesmente colocar os campos que deseja manter dentro do agrupamento _id
. Em seguida, você pode reformar usando $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"
}}
]);
O outro "truque" é usar um nome temporário para o array no estágio de agrupamento. Isso acontece quando você
$project
e alterar o nome, você obtém os campos na ordem especificada na instrução de projeção. Caso contrário, o campo "array_to_sort" não seria o último campo do pedido, pois é copiado do estágio anterior. Essa é uma otimização pretendida em
$project
, mas se você quiser o pedido, poderá fazê-lo como acima. Para estruturas completamente desconhecidas existe a maneira mapReduce de fazer as coisas:
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 } }
)
Claro que tem um formato de saída específico para mapReduce e, portanto, não é exatamente o documento que você tinha, mas todos os campos estão contidos em "valores":
{
"results" : [
{
"_id" : 0,
"value" : {
"_id" : 0,
"some_field" : "a",
"array_to_sort" : [
{
"a" : 1,
"b" : 0
},
{
"a" : 3,
"b" : 3
},
{
"a" : 3,
"b" : 4
}
]
}
}
],
}
Versões futuras (no momento da escrita) permitem que você use um
$$ROOT
variável agregada para representar o 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"}
}}
]);
Portanto, não faz sentido usar o estágio final de "projeto", pois você não conhece os outros campos do documento. Mas todos eles estarão contidos (incluindo o array original e o pedido ) dentro do
_id
campo do documento de resultado.