([email protected] , [email protected] )
TL;RD
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... */
]);
Larga historia:
Después de luchar con la documentación deficiente de la API de Mongoose
, resolví el upsert masivo ajustando updateOne:{}
operación en bulkWrite()
método.
Un par de cosas no documentadas a considerar:
// 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));
});
Las dos cosas clave aquí son problemas de documentación API incompleta (al menos en el momento de escribir este artículo):
'upsert': true
en cada documento . Esto no está documentado en Mongoose API (), que a menudo se refiere a node-mongodb-native conductor. Mirando updateOne en este controlador , podría pensar en agregar'options':{'upsert': true}
, pero, no... eso no funcionará. También traté de agregar ambos casos abulkWrite(,[options],)
argumento, sin ningún efecto tampoco.GasStation.collection.bulkWrite()
. Aunque método Mongoose bulkWrite() afirma que debería llamarseModel.bulkWrite()
(en este caso,GasStation.bulkWrite()
), que activaráMongoError: Unknown modifier: $__
. Entonces,Model.collection.bulkWrite()
debe usarse.
Además, tenga en cuenta:
No necesitas usar el$set
operador mongo enupdateOne.update
campo, ya que mongoose lo maneja en caso de upsert (ver bulkWrite() comentarios en el ejemplo ).- Tenga en cuenta que mi índice único en el esquema (necesario para que upsert funcione correctamente) se define como:
gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });
Espero que ayude.
==> EDITAR:(¿Mangosta 5?)
Como notó @JustinSmith, el $set
El operador agregado por Mongoose ya no parece funcionar. ¿Tal vez sea por Mongoose 5?
En cualquier caso, usando $set
debería hacer explícitamente:
'update': { '$set': gasStation },