猫鼬:$ inc将字段增加指定值的两倍

问题描述 投票:0回答:1

我有一个文件:

{
    "_id" : "5ec8f4454868d203e8e624a3",
    "username" : "Jamie",
    "points" : 25, 
}

我正在使用$ inc增加'points':

model.updateOne({username: "Jamie"},{$inc:{points:5}})

这导致以下结果:

{
    "_id" : "5ec8f4454868d203e8e624a3",
    "username" : "Jamie",
    "points" : 35, 
}

知道为什么它会增加指定值的两倍吗?

这里是实际代码:

app.post("/signup", function(req, resp){
  var parent_id;
  globalvarCollection.findOne({serial:1}, 'current_level', function(doc){
  try{
    current_level=doc.current_level;
    userCollection.countDocuments({level:current_level}, function(doc2){
      userCollection.findOne({level:current_level-1, ttl_chldrn:{$lt:6}}, 'ref_id', function(doc3){
        parent_id=doc3.ref_id;

        userCollection.register({username:req.body.username,
           level:current_level,
           parent_id: parent_id,
           ref_id:"REF"+create_ref_id(),
           ttl_chldrn:0,
           points:0,
           pnts_rdmd_till_date: 0,
           pnts_rdmd_this_month: 0 ,
           jng_date: Date.now(),
          }, req.body.password, async function(err, newDoc){
              if(err){
                resp.render("signup", {signupError:"Server error. Please try later."});
              }
              else{
                currentUser=newDoc;
                passport.authenticate("local")(req, resp, async function(){
                  resp.redirect("/userprofile");

                  //interestingly, $inc is working as expected here:
                  userCollection.updateOne({ref_id:parent_id}, {$inc:{ttl_chldrn: 1}}, async function(){

                    var rem_points=20
                    var ref_id=parent_id;

                    for(let CL=current_level-1; CL>=current_level-4; CL--){
                      //facing the issue here:
                      await userCollection.findOneAndUpdate({ref_id: ref_id, level:CL},{$inc:{points:4}}, function(errDoc1, doc1){
                        if (!errDoc1){
                          ref_id=doc1.parent_id;
                          rem_pts=rem_pts-4;
                        }
                      });
                    }
                    //facing the issue here as well:
                     await userCollection.updateOne({username: "Prince"},{$inc:{points:rem_pts}});

                    });
                  });
                  }
                });
              });
            });
          }
    catch(err){
      resp.render("signup", {signupError:"Server error. Please try later."});
    }
  });
});

我几乎在每个步骤都使用console.log(在此省略了)进行调试,但我看不到任何查询运行两次。尽管我怀疑这可能是异步/等待问题,因为当我删除“ await”时,$ inc可以按预期工作,但是随后删除“ await”会导致您知道其他问题。

node.js mongodb express mongoose
1个回答
0
投票

它肯定被叫过两次。您可能会认为不是,但它是;)

您可以做的一件事情就是添加一个前提条件,这样它就不会同时更新两次。像这样:

model.updateOne(
  {
    username: "Jamie",
    points: 25 // this will fail to match if the points change
  },
  { $inc: { points: 5 } }
)

然后问题是,如何在您不知道的情况下运行两次。您是否通过队列处理程序(例如SQS)运行它?如果是这样,SQS不保证单次交付,您必须确保代码是幂等的。同一个故事,还有其他各种执行方法。

您还如何调试它?将需要更多代码和上下文来进一步提供帮助,但通常$inc只会按您指定的数字增加该值,因此使您增加5并添加10表示该值被两次调用。]

© www.soinside.com 2019 - 2024. All rights reserved.