MongoDB'de findAndModify ve update arasındaki fark nedir?


175

findAndModifyMongoDB'deki yöntemle biraz kafam karıştı . updateYönteme göre avantajı nedir ? Benim için, önce öğeyi döndürüyor ve sonra güncelliyor gibi görünüyor. Ama neden önce öğeyi iade etmeliyim? MongoDB'yi okudum : kesin kılavuz ve kuyrukları manipüle etmek ve get-set tarzı atomisite gerektiren diğer işlemleri gerçekleştirmek için kullanışlı olduğunu söylüyor. Ama bunu nasıl başardığını anlamadım. Birisi bana bunu açıklayabilir mi?

Yanıtlar:


153

Bir öğeyi getirir ve daha sonra güncellerseniz, bu iki adım arasında başka bir iş parçacığı tarafından güncelleme olabilir. Önce bir öğeyi güncelleyip sonra getirirseniz, aralarında başka bir güncelleme olabilir ve güncellediğinizden farklı bir öğe alırsınız.

"Atomik olarak" yapılması, güncellemekte olduğunuz öğenin aynısını geri aldığınızın garantili olduğu anlamına gelir - yani aralarında başka bir işlem olamaz.


6
Hala biraz kafam karıştı. Buna findAndModifymüdahale eden başka bir güncelleme işlemi bulunmadığını nasıl garanti ederim?
chaonextdoor

78
@ chaonextdoor findAndModify, işlemi başlattığında veritabanına bir kilit alır, böylece başka bir işlem çalışırken işleyemez. İşlem bittiğinde kilidi serbest bırakır.
Lycha

4
findAndModify, isteğin bir kısmını değiştirene kadar aslında bir kilit almaz. Bu nedenle, birden çok işlemin aynı kaydı güncelleyebilmesi mümkündür.
Mark Unsworth

5
@MarkUnsworth 10gen ile bir destek vakası açın - findAndModify ile kilitlemede bir hata varsa, mühendislerin en kısa sürede düzeltmek isteyeceğini garanti edebilirim. Birçok kişi bu davranışı raporlasa da bu böyleyse, findAndModify, onu kullanan herkes için tasarlanmış gibi çalışır - istemci tarafında mantık veya uygulama hatalarına gelmemiş gibi görünen durumlar , ancak elbette karmaşık yazılımlarda her zaman bir hata olabilir.
Asya Kamsky

4
@AsyaKamsky Seninle tartışmayı düşünüyordum ama sonra doğru olduğunu fark ettim, şimdi özür dilemeliyim diye düşünüyorum. Afedersiniz!
funkyeah

54

findAndModify belgeyi döndürür, güncelleme yapmaz.

Dwight Merriman'ı (mongoDB'nin orijinal yazarlarından biri) doğru anladıysam, tek bir belgeyi değiştirmek için güncellemeyi kullanmak yani ("multi": false} da atomiktir. Şu anda, eşdeğer güncellemeyi yapmaktan daha hızlı olmalıdır findAndModify.


31

Gönderen MongoDB docs (vurgu eklenmiştir):

  • Varsayılan olarak, her iki işlem de tek bir belgeyi değiştirir. Ancak, çoklu seçeneği ile update () yöntemi birden fazla belgeyi değiştirebilir .

  • Birden çok belge güncelleme ölçütleriyle eşleşiyorsa, findAndModify () için, hangi belgenin güncelleneceğini kontrol etmek için bir ölçü belirtebilirsiniz . Update () yönteminin varsayılan davranışı ile, birden çok belge eşleştiğinde hangi tek belgenin güncelleneceğini belirleyemezsiniz.

  • Varsayılan olarak, findAndModify () yöntemi , belgenin önceden değiştirilmiş sürümünü döndürür . Güncellenmiş belgeyi edinmek için yeni seçeneği kullanın. Update () yöntemi, işlemin durumunu içeren bir WriteResult nesnesi döndürür. Güncellenen belgeyi döndürmek için find () yöntemini kullanın. Ancak, diğer güncellemeler dokümanı, güncellemeniz ve doküman alımı arasında değiştirmiş olabilir. Ayrıca, güncelleme yalnızca tek bir belgeyi değiştirdi, ancak birden fazla belge eşleştiğinde, güncellenen belgeyi tanımlamak için ek mantık kullanmanız gerekir.

  • MongoDB 3.2'den önce, varsayılan yazma endişesini geçersiz kılmak için findAndModify () öğesine bir yazma sorunu belirtemezken MongoDB 2.6'dan bu yana update () yöntemine bir yazma sorunu belirleyebilirsiniz.

Tek bir belgeyi değiştirirken, hem findAndModify () hem de update () yöntemi belgeyi atomik olarak günceller.


1
Güncelleme işlemi için her zaman yazma kaygısı belirleyebilirsiniz. Buna ek olarak, 3.2'den (3.1.1 teknik olarak) findAndModify için de yazma kaygısı belirleyebilirsiniz. jira.mongodb.org/browse/SERVER-6558
Asya

Bulduğum konusu doküman devletler rağmen MongDB 3.6'da findAndModify()varsayılan tuşelere tek doc tarafından update()teneke güncellemeler bir veya daha fazla doktor, bir kullanmak arrayFilters, findAndModify()tüm eşleşmeleri günceller. Belki de bir hatadır?
WesternGun

Hata yoktur - arrayFilters, birden çok dizi öğesini güncellemenize izin verir, ancak bunlar hala tek bir belgededir.
Asya Kamsky

10

Kullanışlı bir kullanım sınıfı sınıfı, sayaçlar ve benzer durumlardır. Örneğin, şu koda bir göz atın (MongoDB testlerinden biri): find_and_modify4.js .

Böylece, findAndModifysayacı arttırır ve artan değerini bir adımda alırsınız. Karşılaştırma: Bu işlemi iki adımda gerçekleştirirseniz ve başka biri (B) adımlarınız arasında aynı işlemi yaparsa, A ve B iki farklı yerine aynı son sayaç değerini alabilir (olası sorunların yalnızca bir örneği).


0

Sayaç işlemleri (inc veya dec) ve diğer tek alanlı mutasyon durumları için findAndModify () kullandık. Uygulamamızı Couchbase'den MongoDB'ye geçirerek, GetAndlock () yapan kodu değiştirmek, içeriği yerel olarak değiştirmek, kaydetmek için () değiştirmek ve güncellenen belgeyi geri almak için tekrar () değiştirmek için bu API'yı buldum. MongoDB ile, güncellenmiş belgeyi döndüren bu tek API'yı kullandım.

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.