([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... */
]);
Lang historie:
Efter at have kæmpet med Mongoose API dårlig dokumentation
, jeg løste bulk upsert tweaking updateOne:{}
operation i bulkWrite()
metode.
Et par udokumenterede ting at overveje:
// 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));
});
De to vigtigste ting her er problemer med ufuldstændig API-dokumentation (i det mindste i skrivende stund):
'upsert': true
i hvert dokument . Dette er ikke dokumenteret i Mongoose API (), som ofte refererer til node-mongodb-native chauffør. Ser på updateOne i denne driver , kunne du tænke dig at tilføje'options':{'upsert': true}
, men nej... det duer ikke. Jeg forsøgte også at tilføje begge tilfælde tilbulkWrite(,[options],)
argument uden effekt heller.GasStation.collection.bulkWrite()
. Selvom Mongoose bulkWrite()-metoden hævder, at den skal heddeModel.bulkWrite()
(i dette tilfældeGasStation.bulkWrite()
), der vil udløseMongoError: Unknown modifier: $__
. SåModel.collection.bulkWrite()
skal bruges.
Bemærk desuden:
Du behøver ikke bruge$set
mongo-operatør iupdateOne.update
felt, da mongoose håndterer det i tilfælde af upsert (se bulkWrite() kommentarer i eksempel ).- Bemærk, at mit unikke indeks i skemaet (kræves for at upsert fungerer korrekt) er defineret som:
gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });
Håber det hjælper.
==> EDIT:(Mongoose 5?)
Som bemærket af @JustinSmith, er $set
operatør tilføjet af Mongoose ser ikke ud til at virke længere. Måske er det på grund af Mongoose 5?
Under alle omstændigheder skal du bruge $set
udtrykkeligt bør gøre:
'update': { '$set': gasStation },