MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Mencoba melakukan upsert massal dengan Mongoose. Apa cara terbersih untuk melakukan ini?

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

Cerita panjang:

Setelah berjuang dengan Dokumentasi buruk API Mongoose , saya memecahkan upser massal mengutak-atik updateOne:{} operasi di bulkWrite() metode.

Beberapa hal yang tidak terdokumentasi untuk dipertimbangkan:

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

Dua hal utama di sini adalah masalah dokumentasi API yang tidak lengkap (setidaknya pada saat penulisan ini ditulis):

  • 'upsert': true di setiap dokumen . Ini tidak didokumentasikan dalam API Mongoose (), yang sering merujuk ke node-mongodb-native pengemudi. Melihat updateOne di driver ini , Anda dapat berpikir untuk menambahkan 'options':{'upsert': true} , tapi, tidak... itu tidak akan berhasil. Saya juga mencoba menambahkan kedua kasus ke bulkWrite(,[options],) argumen, tanpa efek juga.
  • GasStation.collection.bulkWrite() . Meskipun metode luwak bulkWrite() mengklaim itu harus disebut Model.bulkWrite() (dalam hal ini, GasStation.bulkWrite() ), yang akan memicu MongoError: Unknown modifier: $__ . Jadi, Model.collection.bulkWrite() harus digunakan.

Selain itu, perhatikan:

  • Anda tidak perlu menggunakan $set operator mongo di updateOne.update bidang, karena luwak menanganinya jika terjadi upsert (lihat bulkWrite() komentar dalam contoh ).
  • Perhatikan bahwa indeks unik saya dalam skema (diperlukan agar upsert berfungsi dengan baik) didefinisikan sebagai:

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

Semoga membantu.

==> EDIT:(Luwak 5?)

Seperti yang diperhatikan oleh @JustinSmith, $set operator yang ditambahkan oleh Mongoose sepertinya tidak berfungsi lagi. Mungkin karena Mongoose 5?

Bagaimanapun, menggunakan $set secara eksplisit harus dilakukan:

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


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB tidak menggunakan indeks saya

  2. Bagaimana cara mengatur useMongoClient (Mongoose 4.11.0)?

  3. Bagaimana cara menyimpan/menampilkan paragraf dengan mongodb?

  4. Kembalikan Hanya Bidang Tertentu untuk Kueri di Spring Data MongoDB

  5. Mengintegrasikan mongodb dengan neo4j, apakah ada API yang akan menautkannya?