sql >> Database teknologi >  >> NoSQL >> MongoDB

Prøver at lave en bulk upsert med Mongoose. Hvad er den reneste måde at gøre dette på?

([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 historie:

Efter at have kæmpet med Mongoose API dårlig dokumentation , jeg løste bulk upsert tweaking updateOne:{} operation i bulkWrite() metode.

Et par udokumenterede ting at overveje:

// 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 to vigtigste ting her er problemer med ufuldstændig API-dokumentation (i det mindste i skrivende stund):

  • 'upsert': true i hvert dokument . Dette er ikke dokumenteret i Mongoose API (), som ofte refererer til node-mongodb-native chauffør. Ser på updateOne i denne driver , kunne du tænke dig at tilføje 'options':{'upsert': true} , men nej... det duer ikke. Jeg forsøgte også at tilføje begge tilfælde til bulkWrite(,[options],) argument uden effekt heller.
  • GasStation.collection.bulkWrite() . Selvom Mongoose bulkWrite()-metoden hævder, at den skal hedde Model.bulkWrite() (i dette tilfælde GasStation.bulkWrite() ), der vil udløse MongoError: Unknown modifier: $__ . Så Model.collection.bulkWrite() skal bruges.

Bemærk desuden:

  • Du behøver ikke bruge $set mongo-operatør i updateOne.update felt, da mongoose håndterer det i tilfælde af upsert (se bulkWrite() kommentarer i eksempel ).
  • Bemærk, at mit unikke indeks i skemaet (kræves for at upsert fungerer korrekt) er defineret som:

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

Håber det hjælper.

==> EDIT:(Mongoose 5?)

Som bemærket af @JustinSmith, er $set operatør tilføjet af Mongoose ser ikke ud til at virke længere. Måske er det på grund af Mongoose 5?

Under alle omstændigheder skal du bruge $set udtrykkeligt bør gøre:

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


  1. Mongoose &flyde værdier

  2. Aggreger gruppe efter dato med sommertid offset

  3. MongoDB gruppe og sum med id som nøgle

  4. Hvorfor fortæller Express mig, at min standardvisningsmotor ikke er defineret?