MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Ich versuche, einen Bulk-Upsert mit Mongoose durchzuführen. Was ist der sauberste Weg, dies zu tun?

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

Lange Geschichte:

Nach dem Kampf mit mangelhafter Mongoose-API-Dokumentation , habe ich das Bulk-Upsert gelöst Optimieren von updateOne:{} Vorgang im bulkWrite() Methode.

Ein paar undokumentierte Dinge, die es zu beachten gilt:

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

Die beiden wichtigsten Dinge hier sind unvollständige API-Dokumentationsprobleme (zumindest zum Zeitpunkt des Schreibens):

  • 'upsert': true in jedem Dokument . Dies ist in der Mongoose-API () nicht dokumentiert, die sich häufig auf node-mongodb-native bezieht Treiber. Betrachten Sie updateOne in diesem Treiber , könnten Sie daran denken, 'options':{'upsert': true} hinzuzufügen , aber nein ... das geht nicht. Ich habe auch versucht, beide Fälle zu bulkWrite(,[options],) hinzuzufügen Argument, auch ohne Wirkung.
  • GasStation.collection.bulkWrite() . Obwohl Mongoose-bulkWrite()-Methode behauptet, es sollte Model.bulkWrite() heißen (in diesem Fall GasStation.bulkWrite() ), die MongoError: Unknown modifier: $__ auslösen . Also Model.collection.bulkWrite() verwendet werden.

Beachten Sie außerdem:

  • Sie müssen das $set nicht verwenden Mongo-Operator in updateOne.update Feld, da Mongoose es im Fall von Upsert handhabt (siehe bulkWrite()-Kommentare im Beispiel ).
  • Beachten Sie, dass mein eindeutiger Index im Schema (erforderlich, damit Upsert richtig funktioniert) wie folgt definiert ist:

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

Hoffe es hilft.

==> BEARBEITEN:(Mongoose 5?)

Wie von @JustinSmith bemerkt, ist der $set Der von Mongoose hinzugefügte Operator scheint nicht mehr zu funktionieren. Vielleicht liegt es an Mongoose 5?

In jedem Fall mit $set ausdrücklich tun sollte:

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