([email protected] , [email protected] )
TL;DR
await GasStation.collection.bulkWrite([ // <<==== use the model name
{
'updateOne': {
'filter': { 'id': '<some id>' },
'update': { '$set': { /* properties to update */ } },
'upsert': true, // <<==== upsert in every document
}
},
/* other operations here... */
]);
Cerita panjang:
Setelah berjuang dengan Dokumentasi buruk API Mongoose
, saya memecahkan upser massal mengutak-atik updateOne:{}
operasi di bulkWrite()
metode.
Beberapa hal yang tidak terdokumentasi untuk dipertimbangkan:
// suppose:
var GasStation = mongoose.model('gasstation', gasStationsSchema);
var bulkOps = [ ];
// for ( ... each gasStation to upsert ...) {
let gasStation = { country:'a', localId:'b', xyz:'c' };
// [populate gasStation as needed]
// Each document should look like this: (note the 'upsert': true)
let upsertDoc = {
'updateOne': {
'filter': { 'country': gasStation.country, 'localId': gasStation.localId },
'update': gasStation,
'upsert': true
}};
bulkOps.push(upsertDoc);
// end for loop
// now bulkWrite (note the use of 'Model.collection')
GasStation.collection.bulkWrite(bulkOps)
.then( bulkWriteOpResult => {
console.log('BULK update OK');
console.log(JSON.stringify(bulkWriteOpResult, null, 2));
})
.catch( err => {
console.log('BULK update error');
console.log(JSON.stringify(err, null, 2));
});
Dua hal utama di sini adalah masalah dokumentasi API yang tidak lengkap (setidaknya pada saat penulisan ini ditulis):
'upsert': true
di setiap dokumen . Ini tidak didokumentasikan dalam API Mongoose (), yang sering merujuk ke node-mongodb-native pengemudi. Melihat updateOne di driver ini , Anda dapat berpikir untuk menambahkan'options':{'upsert': true}
, tapi, tidak... itu tidak akan berhasil. Saya juga mencoba menambahkan kedua kasus kebulkWrite(,[options],)
argumen, tanpa efek juga.GasStation.collection.bulkWrite()
. Meskipun metode luwak bulkWrite() mengklaim itu harus disebutModel.bulkWrite()
(dalam hal ini,GasStation.bulkWrite()
), yang akan memicuMongoError: Unknown modifier: $__
. Jadi,Model.collection.bulkWrite()
harus digunakan.
Selain itu, perhatikan:
Anda tidak perlu menggunakan$set
operator mongo diupdateOne.update
bidang, karena luwak menanganinya jika terjadi upsert (lihat bulkWrite() komentar dalam contoh ).- Perhatikan bahwa indeks unik saya dalam skema (diperlukan agar upsert berfungsi dengan baik) didefinisikan sebagai:
gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });
Semoga membantu.
==> EDIT:(Luwak 5?)
Seperti yang diperhatikan oleh @JustinSmith, $set
operator yang ditambahkan oleh Mongoose sepertinya tidak berfungsi lagi. Mungkin karena Mongoose 5?
Bagaimanapun, menggunakan $set
secara eksplisit harus dilakukan:
'update': { '$set': gasStation },