1. ホーム
  2. mongodb

[解決済み] ソート順を指定しない場合、MongoDBはどのようにレコードをソートするのですか?

2022-07-23 06:34:43

質問

ソート順を指定せずに Mongo の find() クエリを実行したとき、 データベースは内部的に何を使って結果をソートしているのでしょうか?

によると のドキュメントによると、Mongo のウェブサイトでは :

<ブロッククオート

パラメータなしで find() を実行した場合、データベースは オブジェクトを順次返します。

標準的なテーブルでは、自然順は特に有用ではありません。 自然順序は挿入順序に近いことが多いのですが、そうであることが保証されているわけではありません。 保証されていません。しかし、キャップド・コレクションでは、自然な順序は挿入順序であることが保証されます。 挿入順であることが保証されます。これは非常に便利です。

しかし、標準的なコレクション (キャップされないコレクション) では、結果のソートにどのフィールドが使用されるのでしょうか? それは _id フィールドか何か他のものですか?

編集してください。

基本的に何が言いたいかというと、以下の検索クエリを実行すると

db.collection.find({"x":y}).skip(10000).limit(1000);

二つの異なる時点で t1 t2 で、異なる結果セットを得ることができます。

  1. t1 & t2 の間に追加の書き込みがない場合?
  2. t1 & t2 の間に新しい書き込みがあった場合?
  3. t1 & t2 の間に新しいインデックスが追加されましたか?

私は一時的なデータベースでいくつかのテストを実行し、私が得た結果は同じです ( はい しかし、私は確認したかったのですが、私のテストケースはあまり徹底していなかったと確信しています。

どのように解決するのですか?

ソート順が指定されていない場合のデフォルトの並び順は?

デフォルトの内部ソート順(または ナチュラルオーダー ) は 未定義 実装の詳細です。順序を維持することはストレージエンジンにとって余分なオーバーヘッドであり、 MongoDB の API は明示的な sort() や固定サイズの キャップドコレクション で、関連する 使用制限 . 典型的なワークロードでは、ストレージ エンジンが利用可能な事前割り当て領域の再利用を試み、ディスクとメモリにデータを最も効率的に格納する方法を決定することが望ましいとされています。

クエリーの基準がなければ、結果はストレージエンジンによって 自然な順序 (別名 の順で表示されます。 ). 結果の順序は挿入順序と一致するかもしれませんが、この動作は保証されておらず、(キャップされたコレクションは別として)信頼することはできません。

ストレージの(自然な)順序に影響を与える可能性のあるいくつかの例です。

  • WiredTigerはディスク上のドキュメントとインメモリキャッシュで異なる表現を使っているため、内部データ構造によって自然な順序が変わる可能性があります。
  • オリジナルの MMAPv1 ストレージエンジン (MongoDB 4.2 で削除) は、パディングルールに基づいてドキュメントのレコードスペースを割り当てます。ドキュメントが現在割り当てられているレコードスペースからはみ出すと、 ドキュメントの位置 (と自然な順序) が影響を受けます。削除されたり移動されたりして再利用可能となったストレージに、 新しいドキュメントを挿入することもできます。
  • レプリケーションでは べき乗のオプログ 形式を使用して、レプリカセットメンバー間で一貫して書き込み操作を適用します。各レプリカセットメンバーは、自然な順序で異なることができるローカルデータファイルを維持しますが、oplog更新が適用されたときに同じデータ結果を持つことになります。

インデックスが使用されている場合はどうなりますか?

インデックスが使用されている場合、ドキュメントは見つかった順に返されます(挿入順やI/O順と一致する必要はありません)。複数のインデックスが使用されている場合、その順番は重複排除の過程でどのインデックスが最初にドキュメントを識別したかに内部的に依存します。

予測可能なソート順が必要な場合は でなければなりません。 を明示的に含める必要があります。 sort() を明示し、ソートキーに一意な値を指定する必要があります。

キャップされたコレクションは、どのように挿入順序を維持するのですか? ラムダが自分自身を返す:これは合法か?