MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Опитвам се да направя масово upsert с Mongoose. Кой е най-чистият начин да направите това?

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

Дълга история:

След затруднения с лоша документация за API на Mongoose , разреших груповото добавяне настройване на updateOne:{} операция в bulkWrite() метод.

Няколко недокументирани неща, които трябва да имате предвид:

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

Двете ключови неща тук са проблеми с непълната документация на API (поне към момента на писане):

  • 'upsert': true във всеки документ . Това не е документирано в Mongoose API (), който често се отнася до node-mongodb-native шофьор. Гледайки updateOne в този драйвер , бихте могли да добавите 'options':{'upsert': true} , но не... това няма да стане. Също така се опитах да добавя и двата случая към bulkWrite(,[options],) аргумент, също без ефект.
  • GasStation.collection.bulkWrite() . Въпреки че методът на Mongoose bulkWrite() твърди, че трябва да се нарича Model.bulkWrite() (в този случай, GasStation.bulkWrite() ), което ще задейства MongoError: Unknown modifier: $__ . И така, Model.collection.bulkWrite() трябва да се използва.

Освен това имайте предвид:

  • Не е необходимо да използвате $set mongo оператор в updateOne.update поле, тъй като mongoose го обработва в случай на upsert (вижте bulkWrite() коментари в примера ).
  • Имайте предвид, че моят уникален индекс в схемата (необходим за правилното функциониране на upsert) е дефиниран като:

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

Надявам се да помогне.

==> РЕДАКТИРАНЕ:(Mongoose 5?)

Както забеляза @JustinSmith, $set операторът, добавен от Mongoose, изглежда вече не работи. Може би това е заради Mongoose 5?

Във всеки случай, използвайки $set изрично трябва да направи:

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


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mongo дава грешка при дублиране на ключ за полета с уникално:false

  2. MongoDB начинаещ - да се нормализира или да не се нормализира?

  3. Изграждане на индекс на MongoDB – предотвратяване на потребителите да задействат нови компилации

  4. Динамични заявки на MongoRepository

  5. Заявки с обединения и филтри в Mongoose