sql >> Database >  >> NoSQL >> MongoDB

Ik probeer een bulk-upsert te doen met Mongoose. Wat is de schoonste manier om dit te doen?

([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... */
]);

Lang verhaal:

Na worstelen met Mongoose API slechte documentatie , ik heb de bulk upsert opgelost tweaken van updateOne:{} bewerking in de bulkWrite() methode.

Een paar ongedocumenteerde dingen om te overwegen:

// 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));
  });

De twee belangrijkste dingen hier zijn onvolledige API-documentatieproblemen (tenminste op het moment van schrijven):

  • 'upsert': true in elk document . Dit is niet gedocumenteerd in Mongoose API (), die vaak verwijst naar node-mongodb-native bestuurder. Kijken naar updateOne in dit stuurprogramma , zou je kunnen denken om 'options':{'upsert': true} . toe te voegen , maar nee... dat gaat niet. Ik heb ook geprobeerd beide gevallen toe te voegen aan de bulkWrite(,[options],) argument, ook zonder effect.
  • GasStation.collection.bulkWrite() . Hoewel de Mongoose bulkWrite()-methode beweert dat het Model.bulkWrite() . zou moeten heten (in dit geval GasStation.bulkWrite() ), dat zal MongoError: Unknown modifier: $__ . activeren . Dus, Model.collection.bulkWrite() moet worden gebruikt.

Let bovendien op:

  • U hoeft de $set niet te gebruiken mongo-operator in de updateOne.update veld, aangezien mangoest het afhandelt in geval van upsert (zie bulkWrite() opmerkingen in voorbeeld ).
  • Merk op dat mijn unieke index in het schema (nodig om upsert goed te laten werken) is gedefinieerd als:

gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });

Ik hoop dat het helpt.

==> BEWERKEN:(Mongoes 5?)

Zoals opgemerkt door @JustinSmith, is de $set operator toegevoegd door Mongoose lijkt niet meer te werken. Misschien komt het door Mongoose 5?

Gebruik in ieder geval $set expliciet zou moeten doen:

'update': { '$set': gasStation },


  1. Klasse 'MongoDB\Client' niet gevonden, mongodb-extensie geïnstalleerd

  2. MongoDB $log10

  3. MongoDB - $addToSet op een lijst met ingesloten documenten

  4. MongoDB met Mongoose-limietsubdocumenten