MongoDB, sıralama düzeni belirtilmediğinde kayıtları nasıl sıralar?


103

Herhangi bir sıralama düzeni belirtilmeden bir Mongo find () sorgusu çalıştırdığımızda, veritabanı sonuçları sıralamak için dahili olarak ne kullanır?

Mongo web sitesindeki belgelere göre :

Bir find () parametresiz çalıştırıldığında, veritabanı nesneleri ileri doğal sırayla döndürür.

Standart tablolar için, doğal sıralama özellikle kullanışlı değildir, çünkü sipariş genellikle ekleme siparişine yakın olsa da, olacağı garanti edilmez. Bununla birlikte, Sınırlı Koleksiyonlar için, doğal sıranın kampanya siparişi olacağı garanti edilir. Bu çok faydalı olabilir.

Ancak standart koleksiyonlar (sınırlı olmayan koleksiyonlar) için sonuçları sıralamak için hangi alan kullanılır? _İd alanı mı yoksa başka bir şey mi?

Düzenle:

Temel olarak, ulaşmaya çalıştığım şey şu arama sorgusunu yürütürsem sanırım:

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

Zaman içinde iki farklı noktada: t1 ve t2 , farklı sonuç kümeleri alacak mıyım:

  1. T1 ve t2 arasında hiçbir ek yazma olmadığında?
  2. T1 ve t2 arasında ne zaman yeni yazılar var?
  3. T1 & t2 arasında eklenen yeni dizinler var?

Geçici bir veritabanı üzerinde bazı testler çalıştırdım ve elde ettiğim sonuçlar 3 vakanın tümü için aynı ( Evet ) - ancak emin olmak istedim ve test vakalarımın çok kapsamlı olmadığından eminim.

Yanıtlar:


120

Hiçbiri belirtilmediğinde varsayılan sıralama düzeni nedir?

Varsayılan dahili sıralama düzeni (veya doğal düzen ), tanımlanmamış bir uygulama ayrıntısıdır. Siparişin sürdürülmesi, depolama motorları için fazladan ek yüktür ve MongoDB'nin API'si, ilişkili kullanım kısıtlamaları olan sort()sabit boyutlu sınırlı koleksiyonların açık veya özel bir durumu dışında öngörülebilirliği zorunlu kılmaz . Tipik iş yükleri için, depolama motorunun önceden tahsis edilmiş mevcut alanı yeniden kullanmaya çalışması ve verilerin diskte ve bellekte en verimli şekilde nasıl depolanacağına ilişkin kararlar vermesi arzu edilir.

Herhangi bir sorgu kriteri olmaksızın, sonuçlar depolama motoru tarafından doğal sırayla (diğer bir deyişle bulundukları sırayla ) döndürülür . Sonuç sırası, kampanya siparişiyle çakışabilir ancak bu davranış garanti edilmez ve güvenilemez (sınırlı koleksiyonlar dışında).

Depolama (doğal) düzenini etkileyebilecek bazı örnekler:

  • WiredTiger, diskteki belgelerin bellek içi önbelleğe göre farklı bir temsilini kullanır, bu nedenle doğal sıralama, dahili veri yapılarına bağlı olarak değişebilir.
  • Orijinal MMAPv1 depolama motoru (MongoDB 4.2'de kaldırılmıştır) doldurma kurallarına göre belgeler için kayıt alanı ayırır. Bir belge, halihazırda ayrılmış kayıt alanını aşarsa, belge konumu (ve doğal sıralama) etkilenecektir. Silinen veya taşınan belgeler nedeniyle yeniden kullanıma uygun olarak işaretlenmiş depoya yeni belgeler de eklenebilir.
  • Çoğaltma, yazma işlemlerini çoğaltma kümesi üyeleri arasında tutarlı bir şekilde uygulamak için bir idempotent oplog biçimi kullanır . Her bir çoğaltma kümesi üyesi, doğal sırayla değişebilen yerel veri dosyalarını korur, ancak oplog güncellemeleri uygulandığında aynı veri sonucuna sahip olur.

Ya bir dizin kullanılıyorsa?

Bir dizin kullanılırsa, belgeler bulundukları sırayla iade edilir (bu, ekleme sırası veya G / Ç sırasıyla mutlaka eşleşir). Birden fazla indeks kullanılırsa, sıralama dahili olarak, tekilleştirme işlemi sırasında dokümanı ilk olarak hangi indeksin tanımladığına bağlıdır.

Tahmin edilebilir bir sıralama düzeni istiyorsanız , sorgunuza açık bir şekilde eklemeniz ve sıralama anahtarınız için benzersiz değerlere sahip olmanız gerekirsort() .

Sınırlı koleksiyonlar, ekleme sırasını nasıl korur?

Sınırlı koleksiyonlarda doğal düzen için belirtilen uygulama istisnası, özel kullanım kısıtlamaları tarafından uygulanır: belgeler ekleme sırasına göre saklanır ancak mevcut belge boyutu artırılamaz ve belgeler açıkça silinemez. Sıralama, en eski belgelerin ilk önce "eskimesini" sağlayan sınırlı koleksiyon tasarımının bir parçasıdır.


4
Yani bu aynı find komutunu çalıştırırsam şu anlama gelir: db.collection.find ({"x": y}). Skip (20000) .limit (1000) zaman içinde iki farklı noktada, farklı sonuç alacağım setleri? İki komut arasında herhangi bir yazı yoksa ne olur?
saurabhj

6
@saurabhj: Doğal düzeni etkileyecek bazı örnekler eklendi. Belgeler taşınmış / silinmişse, farklı sonuç kümeleri elde edebilirsiniz. Belge ekleme / güncelleme / silme yoksa, aynı sonucu almalısınız. Dizin eklemek, belgelerin diskteki konumunu etkilemez.
Stennie

7
Çoğaltma kullanıyorsanız , doğal sıralamanın çoğaltma kümesi üyeleri arasında değişiklik gösterebileceğini de eklemelisiniz .
Stennie

Burada yorumlanan 2 noktadan herhangi birini nasıl zorlayacağını bilen var mı? Belgeleri değiştirmeyi denedik, ancak yine de ekleme sıralarında iade ediliyorlar ... Doğal sıranın kampanya siparişinden farklı olup olmadığını merak ediyorum.
Ferran Maylinch

{createdAt: -1}İyimser UI kalıplarını uygulamak için varsayılan bir sıranın (örn. ) Zorunlu kılınması ( bir yaratma / güncelleme / silme işleminden sonra sunucu yanıtını beklemeden önbellekteki veri listelerini güncelleme) gereklidir. Aksi takdirde, istemci tarafındaki iyimser sırayla sunucu yanıt sırasını eşleştiremezsiniz.
Eric Burel

8

Saklanan sırada (dosyadaki sıra) iade edilir, ancak girilen sırada oldukları garanti edilmez. _İd alanına göre sıralanmazlar. Bazen ekleme sırasına göre sıralanmış gibi görünebilir, ancak başka bir istekte değişebilir. Güvenilir değil.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.