MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Próbuję zrobić masowe upsert z Mongoose. Jaki jest najczystszy sposób, aby to zrobić?

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

Długa historia:

Po zmaganiach z słabą dokumentacją interfejsu Mongoose API , rozwiązałem zbiorcze upsert poprawianie updateOne:{} operacja w bulkWrite() metoda.

Kilka nieudokumentowanych rzeczy do rozważenia:

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

Dwie kluczowe rzeczy to niekompletne problemy z dokumentacją API (przynajmniej w momencie pisania):

  • 'upsert': true w każdym dokumencie . Nie jest to udokumentowane w Mongoose API (), które często odnosi się do node-mongodb-native kierowca. Patrząc na updateOne w tym sterowniku , możesz pomyśleć o dodaniu 'options':{'upsert': true} , ale nie... to nie wystarczy. Próbowałem również dodać oba przypadki do bulkWrite(,[options],) argument, również bez efektu.
  • GasStation.collection.bulkWrite() . Chociaż metoda Mongoose bulkWrite() twierdzi, że powinien nazywać się Model.bulkWrite() (w tym przypadku GasStation.bulkWrite() ), co wywoła MongoError: Unknown modifier: $__ . A więc Model.collection.bulkWrite() musi być używany.

Dodatkowo uwaga:

  • Nie musisz używać $set Operator mongo w updateOne.update pole, ponieważ mongoose obsługuje je w przypadku upsert (patrz bulkWrite() w przykładzie ).
  • Zauważ, że mój unikalny indeks w schemacie (potrzebny do prawidłowego działania upsert) jest zdefiniowany jako:

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

Mam nadzieję, że to pomoże.

==> EDYCJA:(Mongusta 5?)

Jak zauważył @JustinSmith, $set operator dodany przez Mongoose wydaje się już nie działać. Może to z powodu Mongoose 5?

W każdym razie, używając $set wyraźnie powinien zrobić:

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


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Odpowiednik ERD dla MongoDB?

  2. Porównaj dwa pola daty w MongoDB

  3. Jak łatwo zarządzać aktualizacjami baz danych i poprawkami bezpieczeństwa

  4. Preferowany schemat MongoDB dla kolekcji osadzonych. dokumenty a tablice

  5. MongoDB:Przekroczono limit czasu po wybraniu serwera przez 30000 ms za pomocą CompositeServerSelector