([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... */
]);
Una lunga storia:
Dopo aver lottato con Documentazione scarsa dell'API Mongoose
, ho risolto il upsert collettivo modifica di updateOne:{}
operazione nel bulkWrite()
metodo.
Un paio di cose non documentate da considerare:
// 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));
});
Le due cose chiave qui sono problemi di documentazione API incompleta (al momento della scrittura, almeno):
'upsert': true
in ogni documento . Questo non è documentato in Mongoose API(), che spesso si riferisce a node-mongodb-native autista. Guardando updateOne in questo driver , potresti pensare di aggiungere'options':{'upsert': true}
, ma, no... non va bene. Ho anche provato ad aggiungere entrambi i casi abulkWrite(,[options],)
argomento, senza alcun effetto.GasStation.collection.bulkWrite()
. Sebbene metodo Mongoose bulkWrite() afferma che dovrebbe essere chiamatoModel.bulkWrite()
(in questo caso,GasStation.bulkWrite()
), che attiveràMongoError: Unknown modifier: $__
. Quindi,Model.collection.bulkWrite()
deve essere utilizzato.
Inoltre, nota:
Non è necessario utilizzare il$set
operatore mongo inupdateOne.update
campo, poiché mongoose lo gestisce in caso di upsert (vedi bulkWrite() nell'esempio ).- Nota che il mio indice univoco nello schema (necessario per il corretto funzionamento dell'upsert) è definito come:
gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });
Spero che aiuti.
==> MODIFICA:(Mangusta 5?)
Come notato da @JustinSmith, il $set
l'operatore aggiunto da Mongoose non sembra funzionare più. Forse è a causa di Mongoose 5?
In ogni caso, utilizzando $set
dovrebbe fare esplicitamente:
'update': { '$set': gasStation },