node.jsmongodbsails.jsmongodb-querywaterline

How to properly do a Bulk upsert/update in MongoDB


I'm trying to:

I'm using a Bulk.unOrderedOperation as I'm also performing a single insert. And I want to do everything in one operation againast DB.

However something it's causing nothing is being inserted for the update/upsert operation.

This is the insert document:

  var lineUpPointsRoundRecord = {
    lineupId: lineup.id,  // String
    totalPoints: roundPoints, // Number
    teamId: lineup.team, // String
    teamName: home.team.name, // String
    userId: home.iduser, // String
    userName: home.user.name, // String
    round: lineup.matchDate.round, // Number
    date: new Date()
  }

This is the upsert document:

  var lineUpPointsGeneralRecord = {
    teamId: lineup.team, // String
    teamName: home.team.name, // String
    userId: home.iduser, // String 
    userName: home.user.name, // String
    round: 0,
    signupPoints: home.signupPoints, // String
    lfPoints: roundPoints+home.signupPoints, // Number 
    roundPoints: [roundPoints] // Number
  };

This is how I'm trying to upsert/update:

var batch = collection.initializeUnorderedBulkOp();

batch.insert(lineUpPointsRoundRecord);

batch.find({team: lineUpPointsRoundRecord.teamId, round: 0}).
  upsert().
  update({
    $setOnInsert: lineUpPointsGeneralRecord,
    $inc: {lfPoints: roundPoints},
    $push: {roundPoints: roundPoints}
  });

batch.execute(function (err, result) {
  return cb(err,result);
});

Why wouldn't it be upserting/updating?

Note

That is JS code using waterline ORM which also uses mongodb native driver.


Solution

  • 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.