([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... */
]);
Longue histoire :
Après avoir lutté avec la mauvaise documentation de l'API Mongoose
, j'ai résolu le upsert en masse peaufiner updateOne:{}
opération dans bulkWrite()
méthode.
Quelques éléments non documentés à prendre en compte :
// 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));
});
Les deux éléments clés ici sont des problèmes de documentation d'API incomplète (au moins au moment de la rédaction) :
'upsert': true
dans chaque document . Ceci n'est pas documenté dans l'API Mongoose (), qui fait souvent référence à node-mongodb-native chauffeur. En regardant updateOne dans ce pilote , vous pourriez penser à ajouter'options':{'upsert': true}
, mais non... ça ne va pas. J'ai également essayé d'ajouter les deux cas aubulkWrite(,[options],)
argument, sans effet non plus.GasStation.collection.bulkWrite()
. Bien que Méthode Mongoose bulkWrite() prétend qu'il devrait s'appelerModel.bulkWrite()
(dans ce cas,GasStation.bulkWrite()
), qui déclencheraMongoError: Unknown modifier: $__
. Donc,Model.collection.bulkWrite()
doit être utilisé.
De plus, notez :
Vous n'avez pas besoin d'utiliser le$set
opérateur mongo dansupdateOne.update
champ, car la mangouste le gère en cas d'upsert (voir les commentaires bulkWrite() dans l'exemple ).- Notez que mon index unique dans le schéma (nécessaire pour que l'upsert fonctionne correctement) est défini comme suit :
gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });
J'espère que ça aide.
==> MODIFIER :(Mongoose 5 ?)
Comme l'a remarqué @JustinSmith, le $set
L'opérateur ajouté par Mongoose ne semble plus fonctionner. C'est peut-être à cause de Mongoose 5 ?
Dans tous les cas, en utilisant $set
devrait explicitement faire :
'update': { '$set': gasStation },