ドキュメント_id
でグループ化しているため 保持したいフィールドをグループ化_id
内に配置するだけです。 。次に、 $project<を使用して再形成できます。 / code>
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"
}}
]);
そこにあるもう1つの「トリック」は、グループ化段階で配列に一時的な名前を使用することです。これは、 $ project
>
名前を変更すると、射影ステートメントで指定された順序でフィールドが取得されます。そうしないと、「array_to_sort」フィールドは前のステージからコピーされるため、順序の最後のフィールドにはなりません。
これは、 $projectで意図された最適化です。コード>
、ただし、注文が必要な場合は、上記のように行うことができます。
完全に未知の構造の場合、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 } }
)
もちろん、これはmapReduceに固有の出力形式であるため、持っていたドキュメントとは異なりますが、すべてのフィールドは「値」の下に含まれています:
{
"results" : [
{
"_id" : 0,
"value" : {
"_id" : 0,
"some_field" : "a",
"array_to_sort" : [
{
"a" : 1,
"b" : 0
},
{
"a" : 3,
"b" : 3
},
{
"a" : 3,
"b" : 4
}
]
}
}
],
}
将来のリリース(執筆時点)では、 $$ ROOT
を使用できます ドキュメントを表すための総計変数:
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"}
}}
]);
したがって、ドキュメント内の他のフィールドを実際に知らないため、最後の「プロジェクト」ステージを使用しても意味がありません。ただし、これらはすべて _id
内に含まれます(元の配列と順序を含む) 結果ドキュメントのフィールド。