Docs Menu
Docs Home
/
MongoDBマニュアル
/ / /

$sort(集計)

項目一覧

  • 定義
  • 互換性
  • 構文
  • 動作
  • $sort 演算子とメモリ
  • $sort 演算子とパフォーマンス
$sort

すべての入力ドキュメントをソートし、ソートされた順序でパイプラインに返す。

次の環境でホストされる配置には $sort を使用できます。

  • MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです

  • MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン

  • MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン

$sortステージのプロトタイプ形式は次のとおりです。

{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }

$sortは、並べ替えるフィールドとそれぞれの並べ替え順序を指定するドキュメントを受け取ります。 <sort order>には次のいずれかの値を指定できます。

説明
1
昇順にソートします。
-1
降順にソートします。
{ $meta: "textScore" }
計算された textScore メタデータで降順にソートします。
の注文。 例については、「テキスト スコア メタデータのソート」を参照してください。

複数のフィールドでソートする場合、ソート順序は左から右に評価されます。たとえば、上記のフォームでは、ドキュメントは最初に <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 フィールドに ManhattanBrooklyn の両方で重複する値が含まれているため、ソート順序に一貫性がない可能性があります。ドキュメントは 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 の値が重複しているドキュメントの順序(ManhattanBrooklyn)は同じではありません。

一貫性のあるソート を実現するには、一意の値のみを含むフィールドをソートに追加します。 次のコマンドは、 $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'を持つドキュメントが返されます。これは、 711のサイズがそれぞれ、 sizes配列のエントリの最小値と最大値であるためです。

ソートの基準となるフィールドについては、次の例のように、ソート順序を 1 または -1 に設定して、それぞれ昇順または降順のソートを指定します。

db.users.aggregate(
[
{ $sort : { age : -1, posts: 1 } }
]
)

この操作は、users コレクション内のドキュメントを age フィールドの降順でソートし、次に posts フィールドの値の昇順でソートします。

ソート操作で異なる BSON types の値を比較する場合、MongoDB は最小値から最大値の順に次の比較順序を使用します。

  1. MinKey(内部型)

  2. null

  3. 数値(ints、longs、doubles、decimals)

  4. シンボル、文字列

  5. オブジェクト

  6. 配列

  7. BinData

  8. ObjectId

  9. ブール値

  10. 日付

  11. タイムスタンプ

  12. 正規表現

  13. MaxKey(内部型)

特定のタイプの比較およびソート順序の詳細については、「比較およびソート順序」を参照してください。

注意

$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$limitに先行し、途中にドキュメント数を変更するステージがない場合、オプティマイザは$limit$sortに統合します。 これにより、 $sort操作の進行中に上位 のn結果のみが保持できます。ここでは、 nは指定された制限であり、MongoDB はメモリにn個の項目のみを保存するだけで済むようになります。 この最適化は、 allowDiskUsetrueで、かつn項目が集計メモリの制限 を超えている場合でも、引き続き適用されます。

最適化はリリースに応じて変更される場合があります。

MongoDB 6.0 以降、 100 MB 以上のメモリを必要とするパイプライン ステージでは、デフォルトで一時ファイルをディスクに書き込みます。これらの一時ファイルはパイプラインの実行中ずっと残り、インスタンスのストレージ容量に影響を与える可能性があります。以前のバージョンの MongoDB では、この動作を有効にするには、個々の find コマンドと aggregate コマンドに { allowDiskUse: true } を渡す必要がありました。

個々の findaggregate コマンドは、次のいずれかの方法で allowDiskUseByDefault パラメーターを上書きできます。

  • allowDiskUseByDefaultfalse に設定されている場合に { allowDiskUse: true } を使用して一時ファイルをディスクに書き込むことを許可する

  • allowDiskUseByDefaulttrue に設定されている場合に { allowDiskUse: false } を使用して一時ファイルがディスクに書き込むことを禁止する

注意

MongoDB Atlas でストレージが長時間実行クエリにより一時ファイルで満杯にするのを防ぐために、ストレージのオートスケーリングを構成することを推奨します。

Atlas クラスターでストレージのオートスケーリングが使用されている場合、一時ファイルによってクラスターが 1 つ上のストレージ階層にスケーリングされる場合があります。

詳しくは、「集計パイプラインの制限」を参照してください。

$sort演算子は、パイプラインの最初のステージで使用される場合、または$matchステージのみの前にある場合は、インデックスを利用できます。

シャーディングされたクラスターで$sortを使用すると、各シャードはインデックスを使用して結果ドキュメントをソートします(使用可能な場合)。 次に、 mongosまたはシャードの 1 つがストリーム マージソートを実行します。

Tip

以下も参照してください。

戻る

$skip