How to properly do a Bulk upsert/update in MongoDB

前端 未结 3 618
梦毁少年i
梦毁少年i 2020-12-10 14:53

I\'m trying to:

  • Find a document according to a search criteria,
  • If found, update some attributes
  • If not insert a document with some attribut
相关标签:
3条回答
  • 2020-12-10 15:26

    Your syntax here is basically correct, but your general execution was wrong and you should have "seperated" the "upsert" action from the other modifications. These will otherwise "clash" and produce an error when an "upsert" occurs:

    LineupPointsRecord.native(function (err,collection) {
    
        var bulk = collection.initializeOrderedBulkOp();
    
        // Match and update only. Do not attempt upsert
        bulk.find({
            "teamId": lineUpPointsGeneralRecord.teamId,
            "round": 0
        }).updateOne({
            "$inc": { "lfPoints": roundPoints },
            "$push": { "roundPoints": roundPoints }
        });
    
        // Attempt upsert with $setOnInsert only
        bulk.find({
            "teamId": lineUpPointsGeneralRecord.teamId,
            "round": 0
        }).upsert().updateOne({
            "$setOnInsert": lineUpPointsGeneralRecord
        });
    
        bulk.execute(function (err,updateResult) {
            sails.log.debug(err,updateResult);
        });
    });
    

    Make sure your sails-mongo is a latest version supporting the Bulk operations properly be the inclusion of a recent node native driver. The most recent supports the v2 driver, which is fine for this.

    0 讨论(0)
  • 2020-12-10 15:26

    Typically I have always set upsert as a property on update. Also update should be able to find the record itself so no need to find it individually.

    Depending on the environment the $ may or may not be necessary.

    batch.update(
     {team: lineUpPointsRoundRecord.teamId, round: 0},
        {      
          $setOnInsert: lineUpPointsGeneralRecord,
          $inc: {lfPoints: roundPoints},
          $push: {roundPoints: roundPoints},
          $upsert: true
        });
    
    0 讨论(0)
  • 2020-12-10 15:44

    I recommend use bulkWrite exemplary code with bulk upsert of many documents:

    In this case you will create documents with unique md5. If document exists then will be updated but no new document is created like in classical insertMany.

    const collection = context.services.get("mongodb-atlas").db("master").collection("fb_posts");
    
    return collection.bulkWrite(
      posts.map(p => { 
        return { updateOne:
          {
            filter: { md5: p.md5 },
            update: {$set: p},
            upsert : true
          }
        }
      }
      ),
      { ordered : false }
    );
    

    https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/

    0 讨论(0)
提交回复
热议问题