私のserコレクションでは、MongoDBは通常、各新しいドキュメントを作成した順序と同じ順序で並べます。最後に作成されたドキュメントはコレクションの最後のドキュメントです。しかし、私が作成した最後のコレクションが27のドキュメントの間で6の位置にある別のコレクションを検出しました。
何故ですか?
MongoDBコレクションの各ドキュメントに続く順序はどれですか?
自然順序 と呼ばれます:
natural order
データベースがディスク上のドキュメントを参照する順序。これがデフォルトのソート順です。
$natural
およびReturn in Natural Order
を参照してください。
これにより、一般に、挿入した順序と同じ順序で取得されることが確認されますが、保証されているわけではありません。
自然な順序で戻る
$natural
パラメーターは、データベース内の 自然順序 に従ってアイテムを返します。この順序は内部実装機能であり、その中の特定の構造に依存しないでください。インデックスの使用
$natural
order donotによる並べ替えを含むクエリは、次の例外を除き、インデックスを使用してクエリ述語を実行します。述語は_id
フィールド{ _id: <value> }
の等価条件であり、$natural
の順序で並べ替えたクエリは_id
インデックスを使用できます。MMAPv1
通常、自然順序は挿入順序を反映しますが、MMAPv1ストレージエンジンについては次の例外があります。 MMAPv1ストレージエンジンでは、 document growth または削除操作によりドキュメントが再配置される場合、自然順序は挿入順序を反映しません。その後、新しく挿入されたドキュメントが占めるスペースを解放します。
明らかに、前述のドキュメントのように、notこのデフォルトの順序に依存する必要があります(この順序は内部実装機能であり、内部の特定の構造に依存しないでください。)。
物事をソートする必要がある場合は、 sort solutions を使用します。
基本的に、次の2つの呼び出しは同じ順序でドキュメントを返します(デフォルトの順序は$natural
であるため):
db.mycollection.find().sort({ "$natural": 1 })
db.mycollection.find()
別のフィールド(たとえば、name
)で並べ替える場合は、次のようにできます。
db.mycollection.find().sort({ "name": 1 })
パフォーマンス上の理由から、MongoDBはハードドライブ上のドキュメントを分割しません。
空のコレクションで開始し、ドキュメントの後にドキュメントを挿入し始めると、mongoDBはそれらをディスクに連続して配置します。
しかし、ドキュメントを更新し、それがより多くのスペースを取り、次のドキュメントをオーバーラップせずに古い位置に収まらなくなったらどうなりますか?その場合、MongoDBはそれを削除し、コレクションファイルの最後に新しいものとして再追加します。
これで、コレクションファイルに未使用のスペースの穴ができました。これはかなり無駄ですよね?そのため、挿入され、その穴に収まるほど小さい次の文書がその穴に挿入されます。これは、2番目のコレクションの場合に発生した可能性があります。
最下行:挿入順序で返されるドキュメントに依存しないでください。順序を気にするときは、常に結果を並べ替えてください。
IonicăBiză が提供するリンク Return in Natural Order のおかげで、それについてもっと知ることができました。
「$ naturalパラメータは、データベース内の自然な順序に従ってアイテムを返します。この順序は内部実装機能であり、その中の特定の構造に依存しないでください。
通常、自然順序は挿入順序を反映しますが、MMAPv1ストレージエンジンについては次の例外があります。 MMAPv1ストレージエンジンの場合、ドキュメントの成長または削除操作のためにドキュメントが再配置された場合、自然順序は挿入順序を反映しません。その後、新しく挿入されたドキュメントが占めるスペースが解放されます。 "
MongoDBは、ユーザーが要求しない限り、ドキュメントを「順序付け」ません。
基本的な挿入では、特に指定しない限り、_id
主キー値に ObjectId
が作成されます。このObjectId
値は、 "単調" または "増加し続ける"プロパティを持つ特別な値です。つまり、作成される各値は最後よりも大きいことが保証されます。
「ソート」したい場合は、明示的な「ソート」を行います。
db.collection.find().sort({ "_id": 1 })
または、 "natural" ソートは、ディスクに保存されている順序で意味します。
db.collection.find().sort({ "$natural": 1 })
特記しない限り、またはソート順を決定するクエリ条件によって「インデックス」が選択されない限り、これはほとんど標準です。しかし、クエリ基準が別の方法でソートされたインデックスを選択した場合、それを使用してその順序を「強制」することができます。
MongoDBドキュメントは成長すると「移動」するため、_id
の順序は、ドキュメントが取得されたときの明示的な順序とは限りません。