([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... */
]);
Lange Geschichte:
Nach dem Kampf mit mangelhafter Mongoose-API-Dokumentation
, habe ich das Bulk-Upsert gelöst Optimieren von updateOne:{}
Vorgang im bulkWrite()
Methode.
Ein paar undokumentierte Dinge, die es zu beachten gilt:
// 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));
});
Die beiden wichtigsten Dinge hier sind unvollständige API-Dokumentationsprobleme (zumindest zum Zeitpunkt des Schreibens):
'upsert': true
in jedem Dokument . Dies ist in der Mongoose-API () nicht dokumentiert, die sich häufig auf node-mongodb-native bezieht Treiber. Betrachten Sie updateOne in diesem Treiber , könnten Sie daran denken,'options':{'upsert': true}
hinzuzufügen , aber nein ... das geht nicht. Ich habe auch versucht, beide Fälle zubulkWrite(,[options],)
hinzuzufügen Argument, auch ohne Wirkung.GasStation.collection.bulkWrite()
. Obwohl Mongoose-bulkWrite()-Methode behauptet, es sollteModel.bulkWrite()
heißen (in diesem FallGasStation.bulkWrite()
), dieMongoError: Unknown modifier: $__
auslösen . AlsoModel.collection.bulkWrite()
verwendet werden.
Beachten Sie außerdem:
Sie müssen das$set
nicht verwenden Mongo-Operator inupdateOne.update
Feld, da Mongoose es im Fall von Upsert handhabt (siehe bulkWrite()-Kommentare im Beispiel ).- Beachten Sie, dass mein eindeutiger Index im Schema (erforderlich, damit Upsert richtig funktioniert) wie folgt definiert ist:
gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });
Hoffe es hilft.
==> BEARBEITEN:(Mongoose 5?)
Wie von @JustinSmith bemerkt, ist der $set
Der von Mongoose hinzugefügte Operator scheint nicht mehr zu funktionieren. Vielleicht liegt es an Mongoose 5?
In jedem Fall mit $set
ausdrücklich tun sollte:
'update': { '$set': gasStation },