Bagaimana cara sortir MongoDB mencatat ketika tidak ada urutan sortir yang ditentukan?

103

Ketika kita menjalankan query Mongo find () tanpa urutan apapun yang ditentukan, apa yang digunakan database secara internal untuk mengurutkan hasil?

Menurut dokumentasi di situs mongo :

Saat menjalankan find () tanpa parameter, database mengembalikan objek dalam urutan alami ke depan.

Untuk tabel standar, urutan natural tidak terlalu berguna karena, meskipun urutannya sering mendekati urutan penyisipan, itu tidak dijamin. Namun, untuk Koleksi Terbatas, urutan alami dijamin menjadi urutan penyisipan. Ini bisa sangat berguna.

Namun untuk koleksi standar (koleksi non capped), bidang apa yang digunakan untuk mengurutkan hasil? Apakah ini bidang _id atau yang lainnya?

Edit:

Pada dasarnya, saya kira apa yang saya coba dapatkan adalah jika saya menjalankan kueri penelusuran berikut:

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

Pada dua titik waktu yang berbeda: t1 dan t2 , apakah saya akan mendapatkan set hasil yang berbeda:

  1. Jika tidak ada penulisan tambahan antara t1 & t2?
  2. Kapan ada penulisan baru antara t1 & t2?
  3. Ada indeks baru yang telah ditambahkan antara t1 & t2?

Saya telah menjalankan beberapa tes pada database temp dan hasil yang saya dapatkan sama ( Ya ) untuk semua 3 kasus - tetapi saya ingin memastikan dan saya yakin bahwa kasus pengujian saya tidak terlalu menyeluruh.

saurabhj
sumber

Jawaban:

121

Apa urutan default saat tidak ada yang ditentukan?

Urutan sortir internal default (atau urutan natural ) adalah detail implementasi yang tidak ditentukan . Menjaga ketertiban adalah biaya tambahan untuk mesin penyimpanan dan API MongoDB tidak mewajibkan prediktabilitas di luar kasus eksplisit sort()atau khusus dari koleksi terbatas berukuran tetap yang memiliki batasan penggunaan terkait . Untuk beban kerja biasa, sebaiknya mesin penyimpanan mencoba menggunakan kembali ruang yang telah dialokasikan sebelumnya dan membuat keputusan tentang cara paling efisien menyimpan data pada disk dan memori.

Tanpa kriteria kueri, hasil akan dikembalikan oleh mesin penyimpanan dalam urutan alami (alias dalam urutan ditemukan ). Urutan hasil mungkin bertepatan dengan urutan penyisipan tetapi perilaku ini tidak dijamin dan tidak dapat diandalkan (selain dari koleksi yang dibatasi).

Beberapa contoh yang dapat mempengaruhi urutan penyimpanan (alami):

  • WiredTiger menggunakan representasi yang berbeda dari dokumen pada disk versus cache dalam memori, sehingga pengurutan alami dapat berubah berdasarkan struktur data internal.
  • Mesin penyimpanan MMAPv1 asli (dihapus di MongoDB 4.2) mengalokasikan ruang rekaman untuk dokumen berdasarkan aturan padding. Jika dokumen melebihi ruang rekaman yang saat ini dialokasikan, lokasi dokumen (dan urutan alami) akan terpengaruh. Dokumen baru juga dapat dimasukkan ke dalam penyimpanan yang ditandai tersedia untuk digunakan kembali karena dokumen yang dihapus atau dipindahkan.
  • Replikasi menggunakan format oplog idempoten untuk menerapkan operasi tulis secara konsisten di seluruh anggota kumpulan replika. Setiap anggota kumpulan replika memelihara file data lokal yang dapat bervariasi dalam urutan alami, tetapi akan memiliki hasil data yang sama ketika pembaruan oplog diterapkan.

Bagaimana jika indeks digunakan?

Jika indeks digunakan, dokumen akan dikembalikan sesuai urutan ditemukannya (yang harus sesuai dengan urutan penyisipan atau urutan I / O). Jika lebih dari satu indeks digunakan maka urutannya bergantung secara internal pada indeks mana yang pertama kali mengidentifikasi dokumen selama proses de-duplikasi.

Jika Anda menginginkan tata urutan yang dapat diprediksi, Anda harus menyertakan eksplisit sort()dengan kueri Anda dan memiliki nilai unik untuk kunci pengurutan Anda.

Bagaimana koleksi yang dibatasi mempertahankan urutan penyisipan?

Pengecualian implementasi yang dicatat untuk tatanan alami dalam koleksi yang dibatasi diberlakukan oleh pembatasan penggunaan khusus mereka: dokumen disimpan dalam urutan penyisipan tetapi ukuran dokumen yang ada tidak dapat ditingkatkan dan dokumen tidak dapat dihapus secara eksplisit. Pemesanan adalah bagian dari desain koleksi terbatas yang memastikan dokumen terlama "usang" terlebih dahulu.

Stennie
sumber
4
Jadi apakah ini berarti bahwa jika saya menjalankan perintah find yang sama: db.collection.find ({"x": y}). Skip (20000) .limit (1000) pada dua titik waktu yang berbeda, saya akan mendapatkan hasil yang berbeda set? Apa yang terjadi jika tidak ada penulisan di antara kedua perintah?
saurabhj
6
@saurabhj: Menambahkan beberapa contoh yang akan mempengaruhi tatanan alam. Jika dokumen telah dipindahkan / dihapus Anda mungkin mendapatkan set hasil yang berbeda. Jika belum ada penyisipan / pembaruan / penghapusan dokumen, Anda akan mendapatkan hasil yang sama. Menambahkan indeks tidak memengaruhi lokasi dokumen di disk.
Stennie
7
Juga harus menambahkan peringatan bahwa jika Anda menggunakan replikasi , urutan alami dapat bervariasi antara anggota set replika.
Stennie
Adakah yang tahu cara memaksa salah satu dari 2 poin yang dikomentari di sini? Kami mencoba mengubah dokumen tetapi mereka masih dikembalikan dalam urutan penyisipannya ... Saya ingin tahu apakah urutan alami dapat berbeda dari urutan penyisipan.
Ferran Maylinch
Menerapkan urutan default (misalnya {createdAt: -1}) diperlukan untuk menerapkan pola UI Optimis (memperbarui daftar data di cache tanpa menunggu respons server setelah membuat / memperbarui / menghapus). Jika tidak, Anda tidak dapat mencocokkan urutan optimis sisi klien dan urutan respons server.
Eric Burel
8

Itu dikembalikan dalam urutan yang disimpan (urutan dalam file), tetapi tidak dijamin bahwa mereka ada dalam urutan yang disisipkan. Mereka tidak diurutkan menurut bidang _id. Kadang-kadang dapat terlihat seperti itu diurutkan berdasarkan urutan penyisipan tetapi dapat berubah dalam permintaan lain. Itu tidak bisa diandalkan.

Parvin Gasimzade
sumber