Mungkin ini saatnya, mungkin ini saya tenggelam dalam dokumentasi yang jarang dan tidak dapat membungkus kepala saya di sekitar konsep memperbarui dalam Mongoose :)
Inilah kesepakatannya:
Saya memiliki skema dan model kontak (properti yang diperpendek):
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var mongooseTypes = require("mongoose-types"),
useTimestamps = mongooseTypes.useTimestamps;
var ContactSchema = new Schema({
phone: {
type: String,
index: {
unique: true,
dropDups: true
}
},
status: {
type: String,
lowercase: true,
trim: true,
default: 'on'
}
});
ContactSchema.plugin(useTimestamps);
var Contact = mongoose.model('Contact', ContactSchema);
Saya menerima permintaan dari klien, berisi bidang yang saya butuhkan dan menggunakan model saya sebagai berikut:
mongoose.connect(connectionString);
var contact = new Contact({
phone: request.phone,
status: request.status
});
Dan sekarang kita mencapai masalah:
- Jika saya menelepon
contact.save(function(err){...})
saya akan menerima kesalahan jika kontak dengan nomor telepon yang sama sudah ada (seperti yang diharapkan - unik) - Saya tidak dapat memanggil
update()
kontak, karena metode itu tidak ada pada dokumen - Jika saya memanggil pembaruan pada model:
Contact.update({phone:request.phone}, contact, {upsert: true}, function(err{...})
Saya masuk ke loop tak terbatas dari beberapa jenis, karena implementasi pembaruan Mongoose jelas tidak ingin objek sebagai parameter kedua. - Jika saya melakukan hal yang sama, tetapi pada parameter kedua saya melewati array asosiatif dari properti permintaan
{status: request.status, phone: request.phone ...}
itu berfungsi - tetapi kemudian saya tidak memiliki referensi ke kontak tertentu dan tidak dapat menemukancreatedAt
danupdatedAt
sifat - sifatnya.
Jadi intinya, setelah semua saya mencoba: diberi dokumen contact
, bagaimana cara memperbaruinya jika ada, atau menambahkannya jika tidak?
Terima kasih atas waktunya.
javascript
mongodb
node.js
mongoose
Bepergian Tek Guy
sumber
sumber
pre
untuksave
?Jawaban:
Mongoose sekarang mendukung ini secara native dengan findOneAndUpdate (panggilan MongoDB findAndModify ).
Opsi upsert = true membuat objek jika tidak ada. default menjadi false .
Dalam versi yang lebih lama, luwak tidak mendukung kaitan ini dengan metode ini:
sumber
Saya baru saja membakar 3 jam yang solid mencoba memecahkan masalah yang sama. Secara khusus, saya ingin "mengganti" seluruh dokumen jika ada, atau menyisipkannya sebaliknya. Inilah solusinya:
Saya membuat masalah pada halaman proyek Mongoose meminta info tentang ini ditambahkan ke dokumen.
sumber
MyModel.update({ age: { $gt: 18 } }, { oldEnough: true }, fn);
danMyModel.update({ name: 'Tobi' }, { ferret: true }, { multi: true }, fn);
Anda dekat dengan
tetapi parameter kedua Anda harus berupa objek dengan operator modifikasi misalnya
sumber
{$set: ... }
bagian di sini sebagai bentuk otomatis bacaan sayaYah, saya menunggu cukup lama dan tidak ada jawaban. Akhirnya menyerah seluruh pendekatan pembaruan / upsert dan pergi dengan:
Apakah itu bekerja? Ya. Apakah saya senang dengan ini? Mungkin tidak. 2 panggilan DB, bukan satu.
Semoga implementasi Mongoose di masa depan akan muncul dengan
Model.upsert
fungsi.sumber
runValidators: true
saat pembaruan: perbarui dokumen (namun, pembaruan validator hanya berjalan di$set
dan$unset
operasi).upsert()
tersedia di semua model. stackoverflow.com/a/50208331/1586406Solusi yang sangat elegan yang dapat Anda capai dengan menggunakan rantai Janji:
sumber
(model) => { return model.save(); }
sebagaimodel => model.save()
, dan juga(err) => { res.send(err); }
sebagaierr => res.send(err)
;)Saya adalah penjaga Mongoose. Cara yang lebih modern untuk menggunakan doc adalah dengan menggunakan
Model.updateOne()
fungsinya .Jika Anda membutuhkan dokumen yang dipasang, Anda dapat menggunakannya
Model.findOneAndUpdate()
Kuncinya adalah Anda perlu meletakkan properti unik di
filter
parameter keupdateOne()
ataufindOneAndUpdate()
, dan properti lainnya diupdate
parameter.Berikut ini adalah tutorial tentang pemasangan dokumen dengan luwak .
sumber
Saya membuat akun StackOverflow HANYA untuk menjawab pertanyaan ini. Setelah sia-sia mencari jalinan, saya sendiri menulis sesuatu. Ini adalah bagaimana saya melakukannya sehingga dapat diterapkan pada model luwak manapun. Baik impor fungsi ini atau tambahkan langsung ke kode Anda di mana Anda melakukan pembaruan.
Kemudian untuk memberikan dokumen luwak lakukan hal berikut,
Solusi ini mungkin memerlukan 2 panggilan DB namun Anda mendapatkan manfaat dari,
Ingatlah bahwa objek tujuan akan selalu menimpa sumber bahkan jika sumber memiliki nilai yang ada
Juga, untuk array, jika objek yang ada memiliki array yang lebih panjang daripada yang menggantikannya maka nilai-nilai di akhir array lama akan tetap. Cara mudah untuk mematikan seluruh array adalah dengan mengatur array lama menjadi array kosong sebelum upsert jika itu yang ingin Anda lakukan.
UPDATE - 01/16/2016 Saya menambahkan kondisi tambahan karena jika ada array nilai primitif, Mongoose tidak menyadari array menjadi diperbarui tanpa menggunakan fungsi "set".
sumber
if(_.isObject(value) && _.keys(value).length !== 0) {
pada kondisi penjaga untuk menghentikan stack overflow. Lodash 4+ di sini, tampaknya mengubah nilai non objek menjadi objek dalamkeys
panggilan sehingga pelindung rekursif selalu benar. Mungkin ada cara yang lebih baik, tetapi sekarang hampir berfungsi untuk saya ...Saya perlu memperbarui / memasang dokumen ke dalam satu koleksi, yang saya lakukan adalah membuat objek literal baru seperti ini:
terdiri dari data yang saya dapatkan dari tempat lain di basis data saya dan kemudian panggil pembaruan pada Model
inilah ouput yang saya dapatkan setelah menjalankan skrip untuk pertama kalinya:
Dan ini adalah output ketika saya menjalankan skrip untuk kedua kalinya:
Saya menggunakan luwak versi 3.6.16
sumber
Berikut ini adalah pendekatan yang lebih baik untuk menyelesaikan metode pembaruan di luwak, Anda dapat memeriksa Scotch.io untuk lebih jelasnya. Ini pasti bekerja untuk saya !!!
sumber
Ada bug yang diperkenalkan di 2.6, dan berdampak ke 2.7 juga
Upert yang digunakan untuk bekerja dengan benar pada 2.4
https://groups.google.com/forum/#!topic/mongodb-user/UcKvx4p4hnY https://jira.mongodb.org/browse/SERVER-13843
Coba lihat, ini berisi beberapa info penting
DIPERBARUI:
Itu tidak berarti upert tidak berfungsi. Berikut ini adalah contoh yang bagus tentang bagaimana menggunakannya:
sumber
Anda cukup memperbarui catatan dengan ini dan mendapatkan data yang diperbarui sebagai tanggapan
sumber
ini bekerja untuk saya.
sumber
Inilah cara paling sederhana untuk membuat / memperbarui sambil juga memanggil middleware dan validator.
sumber
Bagi siapa pun yang tiba di sini masih mencari solusi yang baik untuk "bersemangat" dengan dukungan kait, inilah yang telah saya uji dan bekerja. Masih membutuhkan 2 panggilan DB tetapi jauh lebih stabil daripada apa pun yang saya coba dalam satu panggilan.
sumber
Jika generator tersedia, ini menjadi lebih mudah:
sumber
Tidak ada solusi lain yang bekerja untuk saya. Saya menggunakan permintaan pos dan memperbarui data jika ada yang memasukkannya, _id juga dikirim dengan badan permintaan yang perlu dihapus.
sumber
sumber
sumber
Mengikuti jawaban Traveling Tech Guy , yang sudah luar biasa, kita dapat membuat plugin dan melampirkannya ke luwak setelah kita menginisialisasi sehingga
.upsert()
akan tersedia di semua model.plugins.js
db.js
Maka Anda dapat melakukan sesuatu seperti
User.upsert({ _id: 1 }, { foo: 'bar' })
atauYouModel.upsert({ bar: 'foo' }, { value: 1 })
kapan pun Anda mau.sumber
Saya baru saja kembali ke masalah ini setelah beberapa saat, dan memutuskan untuk menerbitkan plugin berdasarkan jawaban oleh Aaron Mast.
https://www.npmjs.com/package/mongoose-recursive-upsert
Gunakan itu sebagai plugin luwak. Ini menetapkan metode statis yang secara rekursif akan menggabungkan objek yang dilewatkan.
sumber
Script coffeescript ini berfungsi untuk saya dengan Node - caranya adalah agar get _id dicopot dari pembungkus ObjectID-nya ketika dikirim dan dikembalikan dari klien sehingga ini perlu diganti untuk pembaruan (ketika tidak ada _id yang disediakan, simpan akan kembali untuk menyisipkan dan menambahkan satu).
sumber
untuk membangun apa yang diposting Martin Kuzdowicz di atas. Saya menggunakan berikut ini untuk melakukan pembaruan menggunakan luwak dan penggabungan objek json. Bersamaan dengan fungsi model.save () di luwak ini memungkinkan luwak untuk melakukan validasi penuh bahkan yang bergantung pada nilai-nilai lain di json. itu memang membutuhkan paket deepmerge https://www.npmjs.com/package/deepmerge . Tapi itu paket yang sangat ringan.
sumber
req.body
apa adanya, sebelum menguji injeksi NoSQL (lihat owasp.org/index.php/Testing_for_NoSQL_injection ).Setelah membaca posting di atas, saya memutuskan untuk menggunakan kode ini:
jika r adalah nol, kami membuat item baru. Kalau tidak, gunakan upsert dalam pembaruan karena pembaruan tidak membuat item baru.
sumber