Vì bạn đang nhóm trên tài liệu _id
bạn có thể chỉ cần đặt các trường bạn muốn giữ trong nhóm _id
. Sau đó, bạn có thể biểu mẫu lại bằng cách sử dụng $ 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"
}}
]);
Một "mẹo" khác trong đó là sử dụng tên tạm thời cho mảng trong giai đoạn nhóm. Điều này xảy ra khi bạn $ project
và thay đổi tên, bạn sẽ nhận được các trường theo thứ tự được chỉ định trong câu lệnh chiếu. Nếu bạn không làm như vậy, thì trường "array_to_sort" sẽ không phải là trường cuối cùng trong thứ tự, vì nó được sao chép từ giai đoạn trước.
Đó là tối ưu hóa dự kiến trong $ project
, nhưng nếu bạn muốn thứ tự thì bạn có thể làm như trên.
Đối với các cấu trúc hoàn toàn chưa biết, có cách làm của 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 } }
)
Tất nhiên, định dạng đó có định dạng đầu ra dành riêng cho mapReduce và do đó không chính xác là tài liệu bạn có, nhưng tất cả các trường đều được chứa trong "giá trị":
{
"results" : [
{
"_id" : 0,
"value" : {
"_id" : 0,
"some_field" : "a",
"array_to_sort" : [
{
"a" : 1,
"b" : 0
},
{
"a" : 3,
"b" : 3
},
{
"a" : 3,
"b" : 4
}
]
}
}
],
}
Các bản phát hành trong tương lai (kể từ khi viết) cho phép bạn sử dụng $$ ROOT
tổng hợp để đại diện cho tài liệu:
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"}
}}
]);
Vì vậy, không có ích gì khi sử dụng giai đoạn "dự án" cuối cùng vì bạn thực sự không biết các trường khác trong tài liệu. Nhưng tất cả chúng sẽ được chứa (bao gồm mảng và thứ tự ban đầu) trong _id
trường của tài liệu kết quả.