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

cursor.sort()

項目一覧

  • 定義
  • 互換性
  • 構文
  • 動作
  • 自然な順序で返す
cursor.sort(sort)

重要

mongosh メソッド

このページでは、 mongosh メソッドが文書化されます。これは Node.js などの言語固有のドライバーのドキュメントではありません

MongoDB API ドライバーについては、各言語の MongoDB ドライバー ドキュメントを参照してください。

クエリが一致するドキュメントを返す順序を指定します。データベースからドキュメントを取得する前に、カーソルにsort()を適用する必要があります。

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

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

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

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

sort()メソッドには次のパラメーターがあります。

Parameter
タイプ
説明
sort
ドキュメント
結果セットのソート順を定義するドキュメント。

sort パラメーターには、フィールドと値のペアが次の形式で含まれます。

{ field: value }

ソート ドキュメントでは、既存のフィールドで昇順または降順のソートを指定したり、テキスト スコア メタデータでソートしたりできます。

  • 最大 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.find().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.find().sort( { "borough": 1, "_id": 1 } )

_id フィールドには常に一意の値のみが含まれることが保証されているため、同じソートを複数回実行しても返されるソート順序は常に同じになります。

昇順または降順のソートを指定するには、ソート パラメーターで、ソートするフィールドを 1 つまたは複数指定し、1 または -1 の値を指定します。

次の操作では、ドキュメントを最初に age フィールドで降順にソートし、次に posts フィールドで昇順にソートします。

db.users.find({ }).sort( { age : -1, posts: 1 } )

ソート操作で異なる 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" }式を使用して関連性スコアを降順に並べ替えることができます。

次のサンプル ドキュメントでは、 "textScore" メタデータによる降順のソートを指定しています。

db.users.find(
{ $text: { $search: "operating" } },
{ score: { $meta: "textScore" }}
).sort({ score: { $meta: "textScore" } })

"textScore" メタデータは降順でソートされます。

詳細については、$meta を参照してください。

MongoDB が配列値フィールドでドキュメントをソートする場合、ソートキーは昇順か降順かのどちらかによって異なります。

  • 昇順ソートでは、ソートキーは配列内の最小値になります。

  • 降順ソートでは、ソートキーは配列内の最も高い値になります。

クエリフィルターは、ソート キーの選択に影響しません。

たとえば、次のドキュメントを使用してshoesコレクションを作成します。

db.shoes.insertMany( [
{ _id: 'A', sizes: [ 7, 11 ] },
{ _id: 'B', sizes: [ 8, 9, 10 ] }
] )

次のクエリは、ドキュメントをsizesフィールドで昇順と降順でソートします。

// Ascending sort
db.shoes.find().sort( { sizes: 1 } )
// Descending sort
db.shoes.find().sort( { sizes: -1 } )

上記のクエリではどちらのクエリでも、最初に_id: 'A'を持つドキュメントが返されます。これは、 711のサイズがそれぞれ、 sizes配列のエントリの最小値と最大値であるためです。

次のクエリは、 10より大きいサイズの鍵を検索し、結果を鍵サイズの昇順でソートします。

db.shoes.find( { sizes: { $gte: 7 } } ).sort( { sizes: 1 } )

このクエリは、フィルターに7 sizesの条件が含まれているにもかかわらず、最初に_id: 'A'を持つドキュメントを返します。クエリフィルターはソートキーの選択に影響しないためです。

MongoDB は、ソート フィールドを含むインデックスからソート操作の結果を取得できます。MongoDB では、ソートでクエリ述語と同じインデックスを使用する場合 、ソート操作をサポートするために複数のインデックスを使用する場合があります

MongoDB では、1 つまたは複数のインデックスを使用してソート順序を取得できない場合、データに対してブロッキングソート操作を実行する必要があります。ブロッキングソートは、結果を返す前に MongoDB が、ソートへのすべての入力ドキュメントを消費して処理する必要があることを示します。ブロッキングソートは、コレクションまたはデータベースに対する同時操作をブロックしません。

インデックスを使用するソート操作は、多くの場合、ブロッキングソートよりもパフォーマンスが優れています。ソート操作をサポートするインデックスの作成の詳細については、「クエリ結果をソートするためにインデックスを使用する」を参照してください。

MongoDB でのブロッキング ソート操作に 100 メガバイトを超えるシステム メモリが必要な場合、クエリが cursor.allowDiskUse()指定していない限り、MongoDB はエラーを返します。allowDiskUse() を指定することで、MongoDB は 100 メガバイトのシステムメモリ制限を超えるデータをディスク上の一時ファイルに保存し、ブロッキングソート操作を処理することができます。

MongoDB がブロッキングソートを実行する必要があるかどうかを確認するには、クエリにcursor.explain()を追加し、explain の結果を確認します。クエリプランに SORT ステージが含まれている場合、MongoDB は 100 MB のメモリ制限に従ってブロッキングソート操作を実行する必要があります。

ブロッキングソートがメモリを消費しすぎるのを防ぐ方法は次のとおりです。

Tip

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

sort()limit() と組み合わせて使用すると、(ソート順序で)最初の k 個のドキュメントを返すことができます。ここで示した k は指定された制限です。

MongoDB では、ソート順序をインデックススキャンで取得できない場合、Top-k ソートアルゴリズムを使用します。このアルゴリズムでは、基礎となるインデックスやコレクションへのアクセスによってそれまでに確認された結果のうち、最初の(ソート順序によっては最後の) k 件をバッファします。このk件の結果のメモリフットプリントがいずれかの時点で100メガバイトを超えると、クエリでcursor.allowDiskUse()指定されていない限り、クエリは失敗します。

Tip

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

結果セットがソートされ、かつプロジェクションされる場合、MongoDB クエリ エンジンは常に最初にソートを適用します。

コレクション orders には次のドキュメントが含まれています:

{ _id: 1, item: { category: "cake", type: "chiffon" }, amount: 10 }
{ _id: 2, item: { category: "cookies", type: "chocolate chip" }, amount: 50 }
{ _id: 3, item: { category: "cookies", type: "chocolate chip" }, amount: 15 }
{ _id: 4, item: { category: "cake", type: "lemon" }, amount: 30 }
{ _id: 5, item: { category: "cake", type: "carrot" }, amount: 20 }
{ _id: 6, item: { category: "brownies", type: "blondie" }, amount: 10 }

次のクエリは orders コレクションからすべてのドキュメントを返しますが、ソート順を指定していません。

db.orders.find()

このクエリでは、返すドキュメントの順序は次のように一定ではありません。

{ "_id" : 1, "item" : { "category" : "cake", "type" : "chiffon" }, "amount" : 10 }
{ "_id" : 2, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 50 }
{ "_id" : 3, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 15 }
{ "_id" : 4, "item" : { "category" : "cake", "type" : "lemon" }, "amount" : 30 }
{ "_id" : 5, "item" : { "category" : "cake", "type" : "carrot" }, "amount" : 20 }
{ "_id" : 6, "item" : { "category" : "brownies", "type" : "blondie" }, "amount" : 10 }

次のクエリは、 amountフィールドで降順にソートすることを指定します。

db.orders.find().sort( { amount: -1 } )

クエリは、amount の降順で次のドキュメントを返します。

{ "_id" : 2, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 50 }
{ "_id" : 4, "item" : { "category" : "cake", "type" : "lemon" }, "amount" : 30 }
{ "_id" : 5, "item" : { "category" : "cake", "type" : "carrot" }, "amount" : 20 }
{ "_id" : 3, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 15 }
{ "_id" : 1, "item" : { "category" : "cake", "type" : "chiffon" }, "amount" : 10 }
{ "_id" : 6, "item" : { "category" : "brownies", "type" : "blondie" }, "amount" : 10 }

次のクエリは、埋め込みドキュメント item のフィールドを使用してソート順序を指定します。このクエリは、最初に category フィールドを昇順でソートし、次に各 category 内で type フィールドで昇順にソートします。

db.orders.find().sort( { "item.category": 1, "item.type": 1 } )

このクエリでは、次のドキュメントを最初に category フィールドでソートし、各カテゴリ内では type フィールドの順にソートして返します。

{ "_id" : 6, "item" : { "category" : "brownies", "type" : "blondie" }, "amount" : 10 }
{ "_id" : 5, "item" : { "category" : "cake", "type" : "carrot" }, "amount" : 20 }
{ "_id" : 1, "item" : { "category" : "cake", "type" : "chiffon" }, "amount" : 10 }
{ "_id" : 4, "item" : { "category" : "cake", "type" : "lemon" }, "amount" : 30 }
{ "_id" : 2, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 50 }
{ "_id" : 3, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 15 }

$natural パラメーターを使うと、データベース内の自然な順序に従って項目を返します。この順序付けは内部実装機能であり、ドキュメントが特定の順序になることを前提にしないでください。

$natural によるソートを含むクエリでは、次の例外を除き、クエリ述語を実行するためにインデックスは使用されません。クエリ述語が_id フィールド { _id: <value> } の等価条件である場合のみ、$natural によるソートを含むクエリで _id インデックスを使用できます。

Tip

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

戻る

cursor.skip