如何在MongoDB中正确执行批量upsert/update

die*_*lar 8 mongodb node.js mongodb-query sails.js waterline

我试着:

  • 根据搜索条件查找文档,
  • 如果找到,请更新一些属性
  • 如果没有插入带有某些属性的文档.

我正在使用a,Bulk.unOrderedOperation因为我也在执行单个插入.而且我想在一次操作中再做一切DB.

然而,正在为更新/ upsert操作插入一些不会导致任何问题.

这是插入文档:

  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()
  }
Run Code Online (Sandbox Code Playgroud)

这是upsert文档:

  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
  };
Run Code Online (Sandbox Code Playgroud)

这就是我尝试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);
});
Run Code Online (Sandbox Code Playgroud)

为什么不进行上传/更新?

注意

这是使用水线ORM的JS代码,它也使用mongodb本机驱动程序.

Bla*_*ven 11

这里的语法基本上是正确的,但是你的一般执行是错误的,你应该从其他修改中"分离""upsert"动作.否则,当发生"upsert"时,这些将"冲突"并产生错误:

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);
    });
});
Run Code Online (Sandbox Code Playgroud)

确保您的sails-mongo是支持批量操作的最新版本,包括最近的节点本机驱动程序.最新的支持v2驱动程序,这很好.


Dan*_*iel 10

我建议在许多文档中使用bulkWrite示例代码:bulk upsert

在这种情况下,您将创建具有唯一md5. 如果文档存在,则将被更新,但不会像经典中那样创建新文档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 }
);
Run Code Online (Sandbox Code Playgroud)

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