sql >> Databáze >  >> NoSQL >> MongoDB

Zkouším udělat hromadný upsert s Mongoose. Jaký je nejčistší způsob, jak to udělat?

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

Dlouhý příběh:

Po boji s špatná dokumentace rozhraní Mongoose API , vyřešil jsem hromadné upsert ladění updateOne:{} operaci v bulkWrite() metoda.

Pár nezdokumentovaných věcí ke zvážení:

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

Dvě klíčové věci jsou neúplné problémy s dokumentací API (alespoň v době psaní):

  • 'upsert': true v každém dokumentu . Toto není zdokumentováno v Mongoose API (), které často odkazuje na node-mongodb-native Řidič. Podívejte se na updateOne v tomto ovladači , můžete uvažovat o přidání 'options':{'upsert': true} , ale ne... to nepůjde. Také jsem se pokusil přidat oba případy do bulkWrite(,[options],) argument, také bez účinku.
  • GasStation.collection.bulkWrite() . Ačkoli metoda Mongoose bulkWrite() tvrdí, že by se měl jmenovat Model.bulkWrite() (v tomto případě GasStation.bulkWrite() ), která spustí MongoError: Unknown modifier: $__ . Takže Model.collection.bulkWrite() musí být použit.

Poznámka:

  • Nemusíte používat $set operátor mongo v updateOne.update pole, protože mongoose to zpracovává v případě upsert (viz příklad komentáře BulkWrite() ).
  • Všimněte si, že můj jedinečný index ve schématu (potřebný pro správnou funkci upsert) je definován takto:

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

Doufám, že to pomůže.

==> UPRAVIT:(Mongos 5?)

Jak si všiml @JustinSmith, $set Zdá se, že operátor přidaný Mongoose již nefunguje. Možná je to kvůli Mongoose 5?

V každém případě pomocí $set explicitně by měl udělat:

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


  1. Vytvořte textový index s různými tloušťkami polí v MongoDB

  2. Žádná práce s klíčem Mongodb nemůže obsahovat . nebo $?

  3. Jak definovat rozsah shardingu pro každý shard v Mongo?

  4. Načtěte data Spark do Mongo / Memcached pro použití webovou službou