Üretim kodunda Mongoose indeksleme


124

Gelincik Başına dokümantasyon için MongooseJSve MongoDB/ Node.js:

Uygulamanız başladığında Mongoose ensureIndex, şemanızdaki her tanımlı dizini otomatik olarak çağırır . Geliştirme için güzel olsa da, dizin oluşturma önemli bir performans etkisine neden olabileceğinden bu davranışın üretimde devre dışı bırakılması önerilir. Şemanızın autoIndexseçeneğini yanlış olarak ayarlayarak davranışı devre dışı bırakın .

Bu, Mongoose'u Mongo'ya uygulama başlangıcındaki tüm dizinleri baştan sona çalıştırma talimatını vermekten optimize etmek için konuşlandırmadan önce firavun faresinden otomatik indekslemenin kaldırılması talimatını veriyor gibi görünüyor ki bu mantıklı görünüyor.

Üretim kodunda indekslemeyi gerçekleştirmenin doğru yolu nedir? Belki harici bir komut dosyası dizinler oluşturmalı? Ya da ensureIndextek bir uygulama bir koleksiyonun tek okuyucusu / yazıcısı ise, çünkü her DB yazma gerçekleştiğinde bir dizine devam edecekse gereksiz olabilir mi?

Düzenleme: takviyesi için, MongoDB iyi sağlayan belgelere için nasıl yapmak endeksleme, ancak neden ya ne zaman açık indeksleme direktifleri yapılmalıdır. Bana öyle geliyor ki, indekslerin yazar uygulamaları tarafından mevcut indeksleri olan koleksiyonlarda otomatik olarak güncel tutulması gerekiyor ve bu ensureIndexgerçekten tek seferlik bir şey (yeni bir indeks uygulandığında yapılır), bu durumda Mongoose'un autoIndexbir normal bir sunucu yeniden başlatması altında işlem yok.

Yanıtlar:


135

Mongoose belgelerinin neden bu kadar geniş bir şekilde autoIndexüretimde devre dışı bırakmayı önerdiğini hiç anlamadım . Dizin eklendiğinde, sonraki ensureIndexçağrılar dizinin zaten var olduğunu görecek ve sonra geri dönecektir. Dolayısıyla, dizini ilk oluşturduğunuzda yalnızca performans üzerinde bir etkisi vardır ve o sırada koleksiyonlar genellikle boş olduğundan bir dizin oluşturmak yine de hızlı olacaktır.

Benim önerim, autoIndexsize sorun çıkardığı belirli bir durum olmadıkça etkin durumda bırakmaktır ; Milyonlarca dokümanı olan mevcut bir koleksiyona yeni bir dizin eklemek ve oluşturulduğu zaman üzerinde daha fazla kontrol sahibi olmak gibi.


10
Eklemem gereken bir sorum var ... Ya yanlış belirlersem? Verileri eklediğimde dizinler oluşturulacak veya bunu açıkça oluşturmam gerekiyor mu? Bu acemi bir soruysa özür dilerim ama cevaplarsanız çok yardımcı olur.
Saransh Mohapatra

5
@SaranshMohapatra Yanlış olduğunda autoIndex, indekslerini oluşturmak için modelinizde sureIndexes'i çağırmanız gerekir .
JohnnyHK

Onu her seferinde mi yoksa sadece bir kez modeli tanımlarken mi adlandırmam gerekecek?
Saransh Mohapatra

Modelinizi tanımladığınızda (derlediğinizde) @SaranshMohapatra. Bunu uygulamayı ilk başlattığımda yapıyorum. Şimdi zor olan şey, şema değişirse diye tüm dizinleri bırakıp yeniden oluşturmaya karar vermektir.
Moss

3
@JohnnyHK, neredeyse 2016 olmasına rağmen cevabınıza hala katılıyor musunuz?
Alexander Mills

41

Kabul edilen yanıta katılıyorum, ancak MongoDB kılavuzuna göre bunun bir üretim sunucusuna dizin eklemenin önerilen yolu olmadığını belirtmek gerekir:

Uygulamanız sureIndex () işlemlerini içeriyorsa ve diğer operasyonel kaygılar için bir dizin mevcut değilse, dizini oluşturmanın veritabanının performansı üzerinde ciddi bir etkisi olabilir.

Performans sorunlarını önlemek için, uygulamanızın başlangıçta, sürücünüz için getIndexes () yöntemini veya eşdeğer yöntemi kullanarak dizinleri kontrol ettiğinden ve uygun dizinler yoksa sonlandırdığından emin olun. Belirlenen bakım aralıkları sırasında her zaman ayrı uygulama kodu kullanarak üretim örneklerinde dizinler oluşturun.

Tabii ki, gerçekten uygulamanızın nasıl yapılandırıldığına ve dağıtıldığına bağlıdır. Örneğin, Heroku'ya dağıtım yapıyorsanız ve Heroku'nun önyükleme özelliğini kullanmıyorsanız , uygulamanız büyük olasılıkla başlatma sırasında istekleri hiç sunmuyor ve bu nedenle o anda bir dizin oluşturmak muhtemelen güvenlidir.

Buna ek olarak, kabul edilen cevaptan:

Dolayısıyla, dizini ilk oluşturduğunuzda yalnızca performans üzerinde bir etkisi vardır ve o sırada koleksiyonlar genellikle boştur, bu nedenle bir dizin oluşturmak yine de hızlı olacaktır.

Veri modelinizi ve sorgularınızı ilk seferde çivilemeyi başardıysanız, bu sorun değildir ve genellikle durum böyledir. Ancak, dizini olmayan bir mülkte yeni bir DB sorgusuyla uygulamanıza yeni işlevler ekliyorsanız, çoğu zaman kendinizi mevcut birçok belgeyi içeren bir koleksiyona bir dizin eklerken bulacaksınız.

Bu, dizin ekleme konusunda dikkatli olmanız ve bunu yapmanın performans üzerindeki etkilerini dikkatlice düşünmeniz gereken zamandır. Örneğin , dizini arka planda oluşturabilirsiniz :

db.ensureIndex({ name: 1 }, { background: true });

3
Tamam, tüm yapmanız gereken, her koleksiyon için tüm sureIndex geri aramaları başlatılana kadar sunucunuzu BAŞLATMAMAKTIR.
Alexander Mills

@AlexMills bunu nasıl sağlıyorsunuz?
lonelymo

async.each (Object.keys (modeller), function (key, cb) {models [key] .ensureIndexes (cb)}, cb)
Alexander Mills

sadece her bir firavun faresi modelinde sureIndexes'i çağırın, hepsinin bitmesini bekleyin, sonra sunucunuzu başlatın; Ayrıca sunucunuzu başlatmadan önce de db bağlantılarının gerçekleşmesini beklemenizi tavsiye ederim
Alexander Mills

2
Hiçbir yoktur ensureIndexartık. Onun createIndexyerine var. Haklı mıyım
jack blank

1

üretim modunu işlemek için bu blok kodunu kullanın:

const autoIndex = process.env.NODE_ENV !== 'production';
mongoose.connect('mongodb://localhost/collection', { autoIndex });
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.