sql >> Databasteknik >  >> NoSQL >> MongoDB

Försöker göra en bulk upsert med Mongoose. Vad är det renaste sättet att göra detta 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... */
]);

Lång historia:

Efter att ha kämpat med Mongoose API dålig dokumentation , jag löste bulk upsert tweaking updateOne:{} operation i bulkWrite() metod.

Ett par odokumenterade saker att tänka på:

// 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 två viktigaste sakerna här är ofullständiga API-dokumentationsproblem (åtminstone i skrivande stund):

  • 'upsert': true i varje dokument . Detta är inte dokumenterat i Mongoose API (), som ofta refererar till node-mongodb-native förare. Tittar på updateOne i den här drivrutinen , kan du tänka dig att lägga till 'options':{'upsert': true} , men nej... det går inte. Jag försökte också lägga till båda fallen i bulkWrite(,[options],) argument, utan effekt heller.
  • GasStation.collection.bulkWrite() . Även om Mongoose bulkWrite()-metoden hävdar att den ska heta Model.bulkWrite() (i detta fall GasStation.bulkWrite() ), som utlöser MongoError: Unknown modifier: $__ . Så, Model.collection.bulkWrite() måste användas.

Notera dessutom:

  • Du behöver inte använda $set mongo-operator i updateOne.update fältet, eftersom mongoose hanterar det i händelse av upsert (se bulkWrite()-kommentarer i exempel ).
  • Observera att mitt unika index i schemat (behövs för att upsert ska fungera korrekt) är definierat som:

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

Hoppas det hjälper.

==> EDIT:(Mongoose 5?)

Som noterat av @JustinSmith, $set operatör som lagts till av Mongoose verkar inte fungera längre. Kanske är det på grund av Mongoose 5?

Använd i alla fall $set uttryckligen bör göra:

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


  1. MongoDB SpiderMonkey förstår inte UTF-8

  2. $concat två fält i mongodb

  3. hur man frågar med ett specifikt fält istället för id i express js

  4. Använd mock MongoDB-server för enhetstest