sql >> データベース >  >> NoSQL >> MongoDB

マングースでバルクアップサートをしようとしています。これを行うための最もクリーンな方法は何ですか?

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

    長い話:

    MongooseAPIの貧弱なドキュメント に苦労した後 、バルクアップサートを解決しました 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));
      });
    

    ここで重要な2つのことは、不完全なAPIドキュメントの問題です(少なくとも執筆時点では):

    • 'upsert': true 各ドキュメント内 。これは、多くの場合 node-mongodb-native を参照するMongooseAPI()には記載されていません。 運転者。このドライバーのupdateOne を見る 、'options':{'upsert': true}を追加することを考えることができます 、しかし、いいえ...それはしません。また、両方のケースをbulkWrite(,[options],)に追加しようとしました 引数、効果もありません。
    • GasStation.collection.bulkWrite()マングースbulkWrite()メソッド Model.bulkWrite()と呼ばれるべきだと主張している (この場合、GasStation.bulkWrite() )、これによりMongoError: Unknown modifier: $__がトリガーされます 。したがって、Model.collection.bulkWrite() 使用する必要があります。

    さらに、注意:

    • $setを使用する必要はありません updateOne.updateのmongo演算子 フィールド、マングースはアップサートの場合にそれを処理するため(例のbulkWrite()コメントを参照
    • スキーマ内の一意のインデックス(upsertが正しく機能するために必要)は次のように定義されていることに注意してください:

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

    お役に立てば幸いです。

    ==>編集:(マングース5?)

    @JustinSmithが気付いたように、$set Mongooseによって追加された演算子はもう機能していないようです。多分それはマングース5のせいですか?

    いずれにせよ、$setを使用します 明示的に行う必要があります:

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


    1. MongoFactoryBeanとSimpleMongoDbFactoryの違い

    2. mongodbリポジトリにカスタムクエリを書き込む

    3. MongoDB $ pullAll

    4. ポートフォワーディングの問題を介したVagrant上のMongoDB