Apa perbedaan antara findAndModify dan pembaruan di MongoDB?

175

Saya sedikit bingung dengan findAndModifymetode di MongoDB. Apa keuntungannya dibandingkan updatemetode ini? Bagi saya, sepertinya itu hanya mengembalikan item terlebih dahulu dan kemudian memperbaruinya. Tetapi mengapa saya harus mengembalikan barang terlebih dahulu? Saya membaca MongoDB: panduan definitif dan ia mengatakan bahwa itu berguna untuk memanipulasi antrian dan melakukan operasi lain yang memerlukan atomisitas gaya get-and-set. Tetapi saya tidak mengerti bagaimana cara mencapai ini. Adakah yang bisa menjelaskan hal ini kepada saya?

chaonextdoor
sumber

Jawaban:

153

Jika Anda mengambil item dan kemudian memperbaruinya, mungkin ada pembaruan oleh utas lain antara kedua langkah tersebut. Jika Anda memperbarui item terlebih dahulu dan kemudian mengambilnya, mungkin ada pembaruan lain di antaranya dan Anda akan mendapatkan kembali item yang berbeda dari yang Anda perbarui.

Melakukannya "secara atomis" berarti Anda dijamin akan mendapatkan kembali item yang sama persis dengan yang Anda perbarui - artinya tidak ada operasi lain di antaranya.

Asya Kamsky
sumber
6
Saya masih sedikit bingung. Bagaimana findAndModifyjaminan bahwa tidak ada operasi pembaruan lainnya yang mengganggu itu?
chaonextdoor
78
@chaonextdoor findAndModify memperoleh kunci ke database saat memulai operasi sehingga tidak ada operasi lain yang dapat memproses ketika sedang berjalan. Ketika selesai operasi itu melepaskan kunci.
Lycha
4
findAndModify tidak benar-benar mendapatkan kunci sampai memodifikasi bagian permintaan. Jadi dimungkinkan untuk beberapa proses untuk dapat memperbarui catatan yang sama.
Mark Unsworth
5
@MarkUnsworth membuka kasus dukungan dengan 10gen - jika ada bug dalam penguncian dengan findAndModify, saya dapat menjamin Anda para insinyur ingin segera memperbaikinya. Jika itu masalahnya, kita akan melihat banyak orang melaporkan perilaku ini, tetapi findAndModify berfungsi sebagai dirancang untuk hampir semua orang yang menggunakannya - kasus-kasus di mana sepertinya bukan karena logika atau bug implementasi di sisi klien , tapi tentu saja dalam perangkat lunak yang kompleks selalu ada bug.
Asya Kamsky
4
@ AsyaKamsky saya sedang mempertimbangkan untuk berdebat dengan Anda tetapi kemudian menyadari bahwa Anda benar, jadi sekarang saya berpikir saya harus meminta maaf. Maaf!
funkyeah
54

findAndModify mengembalikan dokumen, pembaruan tidak.

Jika saya memahami Dwight Merriman (salah satu penulis asli mongoDB) dengan benar, menggunakan pembaruan untuk mengubah satu dokumen yaitu ("multi": false} juga atom. Saat ini, itu juga harus lebih cepat daripada melakukan menggunakan pembaruan yang setara menggunakan findAndModify.

Yaniv
sumber
31

Dari dokumen MongoDB (penekanan ditambahkan):

  • Secara default, kedua operasi memodifikasi satu dokumen. Namun, metode pembaruan () dengan multi-opsi dapat memodifikasi lebih dari satu dokumen .

  • Jika beberapa dokumen cocok dengan kriteria pembaruan, untuk findAndModify (), Anda dapat menentukan jenis untuk memberikan sejumlah kontrol pada dokumen mana yang akan diperbarui. Dengan perilaku default metode pembaruan (), Anda tidak dapat menentukan satu dokumen mana yang akan diperbarui ketika beberapa dokumen cocok.

  • Secara default, metode findAndModify () mengembalikan versi dokumen yang sudah dimodifikasi . Untuk mendapatkan dokumen yang diperbarui, gunakan opsi baru. Metode pembaruan () mengembalikan objek WriteResult yang berisi status operasi. Untuk mengembalikan dokumen yang diperbarui, gunakan metode find (). Namun, pembaruan lain mungkin telah memodifikasi dokumen antara pembaruan Anda dan pengambilan dokumen. Juga, jika pembaruan hanya memodifikasi satu dokumen tetapi beberapa dokumen cocok, Anda harus menggunakan logika tambahan untuk mengidentifikasi dokumen yang diperbarui.

  • Sebelum MongoDB 3.2 Anda tidak dapat menentukan masalah penulisan untuk menemukanAndModify () untuk mengganti masalah penulisan default sedangkan Anda dapat menentukan masalah penulisan untuk metode pembaruan () sejak MongoDB 2.6.

Saat memodifikasi satu dokumen, metode findAndModify () dan pembaruan () memperbarui dokumen secara atomis.

Tamlyn
sumber
1
Anda selalu dapat menentukan perhatian penulisan untuk memperbarui operasi. Selain itu, karena 3.2 (3.1.1 secara teknis), Anda dapat menentukan perhatian penulisan untuk menemukanAndModify juga. jira.mongodb.org/browse/SERVER-6558
Asya Kamsky
Saya telah menemukan bahwa di MongDB 3.6, meskipun dokumen menyatakan findAndModify()secara default memodifikasi hanya satu dokumen dan update()dapat memperbarui satu atau lebih dokumen, ketika saya menggunakan arrayFilters, findAndModify()pembaruan semua pertandingan. Mungkin itu bug ??
WesternGun
Tidak ada bug - arrayFilters memungkinkan Anda memperbarui beberapa elemen array tetapi masih dalam satu dokumen.
Asya Kamsky
10

Satu kelas kasus penggunaan yang berguna adalah penghitung dan kasus serupa. Misalnya, lihat kode ini (salah satu tes MongoDB): find_and_modify4.js .

Jadi, dengan findAndModifyAnda menambah penghitung dan dapatkan nilainya yang bertambah dalam satu langkah. Bandingkan: jika Anda (A) melakukan operasi ini dalam dua langkah dan orang lain (B) melakukan operasi yang sama di antara langkah-langkah Anda maka A dan B mungkin mendapatkan nilai penghitung terakhir yang sama dan bukannya dua berbeda (hanya satu contoh masalah yang mungkin).

Roman Kuzmin
sumber
0

Kami menggunakan findAndModify () untuk operasi Penghitung (inc atau dec) dan bidang tunggal lainnya bermutasi kasus. Memigrasi aplikasi kami dari Couchbase ke MongoDB, saya menemukan API ini untuk menggantikan kode yang tidak GetAndlock (), memodifikasi konten secara lokal, ganti () untuk menyimpan dan Dapatkan () lagi untuk mengambil kembali dokumen yang diperbarui. Dengan mongoDB, saya hanya menggunakan API tunggal ini yang mengembalikan dokumen yang diperbarui.

Manju Kori
sumber