定義
互換性
次の環境でホストされる配置には $sort を使用できます。
- MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです 
- MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン 
- MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン 
構文
$sortステージのプロトタイプ形式は次のとおりです。
{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } } 
$sortは、並べ替えるフィールドとそれぞれの並べ替え順序を指定するドキュメントを受け取ります。 <sort order>には次のいずれかの値を指定できます。
| 値 | 説明 | 
|---|---|
| 
 | 昇順にソートします。 | 
| 
 | 降順にソートします。 | 
| 
 | 
 | 
複数のフィールドでソートする場合、ソート順序は左から右に評価されます。たとえば、上記のフォームでは、ドキュメントは最初に <field1> でソートされます。次に、同じ <field1> 値を持つドキュメントが <field2> によってさらにソートされます。
動作
パフォーマンス
$sort はブロッキング ステージであり、パイプラインはデータを処理する前にすべての入力データが検索されるまで待機します。ブロッキング ステージは、複数のステージを持つパイプラインの並列処理を減らすため、パフォーマンスを低下させる可能性があります。ブロッキング ステージでは、大規模なデータセットに対して大量のメモリが使用される場合もあります。
制限
- 最大 32 個のキーでソートすることができます。 
- 重複するフィールドを含むソート パターンを指定すると、エラーが発生します。 
ソートの一貫性
MongoDB では、コレクション内のドキュメントを特定の順序で保存することはありません。重複する値を含むフィールドでソートする場合、それらの値を含むドキュメントは任意の順序で返されます。
一貫したソート順序が必要な場合は、一意の値を含むフィールドを少なくとも 1 つ含めてソートしてください。これを保証する最も簡単な方法は、_idフィールドをソートのクエリに含めることです。
次の restaurant コレクションについて考えてみます。
db.restaurants.insertMany( [    { "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan"},    { "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens"},    { "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn"},    { "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan"},    { "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn"}, ] ) 
次のコマンドは、 $sort ステージを使用して borough フィールドでソートします。
db.restaurants.aggregate(    [      { $sort : { borough : 1 } }    ] ) 
この例では、borough フィールドに Manhattan と Brooklyn の両方で重複する値が含まれているため、ソート順序に一貫性がない可能性があります。ドキュメントは borough のアルファベット順に返されますが、borough の値が重複しているドキュメントでは、同じソートを複数回実行すると順序が異なる場合があります。たとえば、上記のコマンドを 2 回実行した結果を次に示します。
{ "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn" } { "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn" } { "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan" } { "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan" } { "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens" } { "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn" } { "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn" } { "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan" } { "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan" } { "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens" } 
borough の値はまだアルファベット順にソートされていますが、borough の値が重複しているドキュメントの順序(Manhattan と Brooklyn)は同じではありません。
一貫性のあるソート を実現するには、一意の値のみを含むフィールドをソートに追加します。 次のコマンドは、 $sortステージを使用して、 boroughフィールドと_idフィールドの両方でソートします。
db.restaurants.aggregate(    [      { $sort : { borough : 1, _id: 1 } }    ] ) 
_id フィールドには常に一意の値のみが含まれることが保証されているため、同じソートを複数回実行しても返されるソート順序は常に同じになります。
配列フィールドによるソート
MongoDB が配列値フィールドでドキュメントをソートする場合、ソートキーは昇順か降順かのどちらかによって異なります。
- 昇順ソートでは、ソートキーは配列内の最小値になります。 
- 降順ソートでは、ソートキーは配列内の最も高い値になります。 
クエリフィルターは、ソート キーの選択に影響しません。
たとえば、次のドキュメントを使用してshoesコレクションを作成します。
db.shoes.insertMany( [    { _id: 'A', sizes: [ 7, 11 ] },    { _id: 'B', sizes: [ 8, 9, 10 ] } ] ) 
次のクエリは、ドキュメントをsizesフィールドで昇順と降順でソートします。
// Ascending sort db.shoes.aggregate( [    {       $sort: { sizes: 1 }    } ] ) // Descending sort db.shoes.aggregate( [    {       $sort: { sizes: -1 }    } ] ) 
上記のクエリではどちらのクエリでも、最初に_id: 'A'を持つドキュメントが返されます。これは、 7と11のサイズがそれぞれ、 sizes配列のエントリの最小値と最大値であるためです。
例
昇順および降順ソート
ソートの基準となるフィールドについては、次の例のように、ソート順序を 1 または -1 に設定して、それぞれ昇順または降順のソートを指定します。
db.users.aggregate(    [      { $sort : { age : -1, posts: 1 } }    ] ) 
この操作は、users コレクション内のドキュメントを age フィールドの降順でソートし、次に posts フィールドの値の昇順でソートします。
ソート操作で異なる BSON types の値を比較する場合、MongoDB は最小値から最大値の順に次の比較順序を使用します。
- MinKey(内部型) 
- null 
- 数値(ints、longs、doubles、decimals) 
- シンボル、文字列 
- オブジェクト 
- 配列 
- BinData 
- ObjectId 
- ブール値 
- 日付 
- タイムスタンプ 
- 正規表現 
- JavaScriptコード 
- MaxKey(内部型) 
特定のタイプの比較およびソート順序の詳細については、「比較およびソート順序」を参照してください。
Text Score Metadata Sort
注意
$text は、自己管理型(Atlas 以外)配置に対するテキスト クエリ機能を提供します。MongoDB Atlas でホストされているデータに対して、MongoDB は改良された全文クエリ ソリューションである Atlas Search を提供します。
$text を含むパイプラインでは、{ $meta: "textScore"
} 式を使用して関連性スコアを降順に並べ替えることができます。{ <sort-key> } ドキュメントで、{ $meta: "textScore" } 式を無作為のフィールド名に設定します。フィールド名はクエリ システムによって無視されます。以下に例を挙げます。
db.users.aggregate(    [      { $match: { $text: { $search: "operating" } } },      { $sort: { score: { $meta: "textScore" }, posts: -1 } }    ] ) 
この操作では、 $text演算子を使用してドキュメントを一致させ、最初に"textScore"メタデータを降順でソートし、次にpostsフィールドで降順にソートします。 ソート ドキュメント内のscoreフィールド名はクエリ システムによって無視されます。 このパイプラインでは、 "textScore"メタデータはプロジェクションに含まれておらず、一致するドキュメントの一部として返されません。 詳しくは、 $metaを参照してください。
$sort 演算子とメモリ
$sort +$limit メモリの最適化
$sortが$limitに先行し、途中にドキュメント数を変更するステージがない場合、オプティマイザは$limitを$sortに統合します。 これにより、 $sort操作の進行中に上位 のn結果のみが保持できます。ここでは、 nは指定された制限であり、MongoDB はメモリにn個の項目のみを保存するだけで済むようになります。 この最適化は、 allowDiskUseがtrueで、かつn項目が集計メモリの制限 を超えている場合でも、引き続き適用されます。
最適化はリリースに応じて変更される場合があります。
$sort およびメモリ制限
$sortステージでは、メモリ内ソートの RAM が100 MB に制限されています。 デフォルトでは、 ステージがこの制限を超えると、 $sortはエラーを発生させます。 パイプライン処理がより多くのスペースを使用できるようにするには、 allowDiskUseオプションを使用して集計パイプライン ステージで一時ファイルにデータを書込みます。
Tip
$sort 演算子とパフォーマンス
$sort演算子は、パイプラインの最初のステージで使用される場合、または$matchステージのみの前にある場合は、インデックスを利用できます。
シャーディングされたクラスターで$sortを使用すると、各シャードはインデックスを使用して結果ドキュメントをソートします(使用可能な場合)。 次に、 mongosまたはシャードの 1 つがストリーム マージソートを実行します。