([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... */
]);
Długa historia:
Po zmaganiach z słabą dokumentacją interfejsu Mongoose API
, rozwiązałem zbiorcze upsert poprawianie updateOne:{}
operacja w bulkWrite()
metoda.
Kilka nieudokumentowanych rzeczy do rozważenia:
// 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));
});
Dwie kluczowe rzeczy to niekompletne problemy z dokumentacją API (przynajmniej w momencie pisania):
'upsert': true
w każdym dokumencie . Nie jest to udokumentowane w Mongoose API (), które często odnosi się do node-mongodb-native kierowca. Patrząc na updateOne w tym sterowniku , możesz pomyśleć o dodaniu'options':{'upsert': true}
, ale nie... to nie wystarczy. Próbowałem również dodać oba przypadki dobulkWrite(,[options],)
argument, również bez efektu.GasStation.collection.bulkWrite()
. Chociaż metoda Mongoose bulkWrite() twierdzi, że powinien nazywać sięModel.bulkWrite()
(w tym przypadkuGasStation.bulkWrite()
), co wywołaMongoError: Unknown modifier: $__
. A więcModel.collection.bulkWrite()
musi być używany.
Dodatkowo uwaga:
Nie musisz używać$set
Operator mongo wupdateOne.update
pole, ponieważ mongoose obsługuje je w przypadku upsert (patrz bulkWrite() w przykładzie ).- Zauważ, że mój unikalny indeks w schemacie (potrzebny do prawidłowego działania upsert) jest zdefiniowany jako:
gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });
Mam nadzieję, że to pomoże.
==> EDYCJA:(Mongusta 5?)
Jak zauważył @JustinSmith, $set
operator dodany przez Mongoose wydaje się już nie działać. Może to z powodu Mongoose 5?
W każdym razie, używając $set
wyraźnie powinien zrobić:
'update': { '$set': gasStation },