mongoose .create 语句不保存在 async.each 循环中

mongoose .create statement not saving inside async.each loop

在我的 之后,我的异步循环开始工作了,但是我 运行 遇到了一个新问题。循环创建的文档似乎没有保存到数据库中。然而,它们被推送到父记录中(下面的计划 incode),并且成功保存了推送。我在下面包含了完整的路线代码:

// Auto-populate entries
router.post( "/populate", middlewareObj.isLoggedIn, function(req, res){
  var orgList=[]

  console.log( req.body.orgs);

  if (typeof req.body.orgs == 'string') {
    orgList = [req.body.orgs]
  } else {
    orgList = req.body.orgs
  };

  orgList.save
  console.log( orgList)

  //lookup Plan using ID
  Plan.findById( req.params.id, function(err, foundPlan){
    if(err){
      console.log( err);
      res.redirect("/plans");
    } else {
      BaseData.find({
        "contributingRegion": foundPlan.contributingRegion,
        "org": { $in: orgList}
      }, function( err, baseData) {
        if (err) {
          console.log( err)
        } else {
          console.log( baseData.length);

          //Create entries & push into plan
          async.each( baseData, function(data, next) {
              Entry.create(data, function(err, entry) {             /*Create entry*/
                if(err) {
                  next (err);
                } else {
                  // Create other entry variables
                  entry.author.id = req.user._id;
                  entry.author.username = req.user.username;
                  entry.save();
                  entry.adjHC                  = entry.initHC;
                  entry.adjResRate             = entry.initResRate;
                  entry.yr1Resignations        = Math.round(entry.adjHC * entry.adjResRate);
                  entry.yr1Supply              = entry.adjHC - entry.yr1Resignations;
                  entry.yr2Resignations        = Math.round(entry.yr1Supply * entry.adjResRate);
                  entry.yr2Supply              = entry.yr1Supply - entry.yr2Resignations;
                  entry.yr3Resignations        = Math.round(entry.yr2Supply * entry.adjResRate);
                  entry.yr3Supply              = entry.yr2Supply - entry.yr3Resignations;
                  entry.yr4Resignations        = Math.round(entry.yr3Supply * entry.adjResRate);
                  entry.yr4Supply              = entry.yr3Supply - entry.yr4Resignations;
                  entry.yr5Resignations        = Math.round(entry.yr4Supply * entry.adjResRate);
                  entry.yr5Supply              = entry.yr4Supply- entry.yr5Resignations;
                  entry.demandYr0              = entry.adjHC;
                  entry.demandYr1              = entry.adjHC;
                  entry.demandYr2              = entry.adjHC;
                  entry.demandYr3              = entry.adjHC;
                  entry.demandYr4              = entry.adjHC;
                  entry.demandYr5              = entry.adjHC;
                  entry.gapYr1                 = entry.yr1Supply - entry.demandYr1;
                  entry.gapYr2                 = entry.yr2Supply - entry.demandYr2;
                  entry.gapYr3                 = entry.yr3Supply - entry.demandYr3;
                  entry.gapYr4                 = entry.yr4Supply - entry.demandYr4;
                  entry.gapYr5                 = entry.yr5Supply - entry.demandYr5;
                  entry.save();
                  console.log(entry._id + ' saved')
                  foundPlan.planEntries.push(entry);
                  foundPlan.save();
                  // next iteration
                  next();         
                }
              });   /*entry Create*/

          }, function(err) {
            // This function runs when all iterations are done
            if (err) throw err;
            res.redirect('/plans/' + foundPlan._id);
          } );  /*End of Async Loop*/
        };
      });     /*End of BaseDate.find*/
    }         
  });         /*End of Plan.findById*/
});

从我一直用来进行故障排除的代码中的各种 console.logs 中,我知道代码正在找到 baseData 中正确数量的条目(42 条记录)。

我应该添加相同的 Entry.create 代码用于单独的路由,其中​​条目由用户逐个手动添加。

当我查看 mongodb 本身以查看计划中 planEntries 数组的大小时,我得到:

// 1) Manually added entry                                                                              
    { "_id" : ObjectId("5a6f00421046d90019e2c6e8"), "name" : "test", "numEntries" : 1 }

// 2) After First populate route                                                                             
    { "_id" : ObjectId("5a6f00421046d90019e2c6e8"), "name" : "test", "numEntries" : 46 } 

// 3) After a second populate route (same selections)                                                                         
    { "_id" : ObjectId("5a6f00421046d90019e2c6e8"), "name" : "test", "numEntries" : 239 }  

手动添加的条目保存正确,但其他条目似乎没有保存文档。

同样出乎意料的是,在每次自动填充之后,我预计 numEmtries 会增加 42,但它似乎增加了更多的数字

所以设法解决了。发生了两件事。

首先,Entry.create 创建对象但由于某种原因不允许将其保存到数据库中。如果我将我的代码交换为 var entry = new ENTRY(),那么它会将它们保存到数据库中。

一旦我开始工作,我 运行 进入了一个问题,即每个条目被多次传递到计划中(与要添加的条目的次数相同,所以我最终得到 42 * 42条目)。通过在调用 next() 函数之前清除 entry 对象解决了这个问题。我也切换到async.eachSeries。我稍后会测试 async.each,看看是否可行。

更新:async.each 恢复到重复结果,似乎需要 async.eachSeries 来防止重复。

完整的最终代码:

// Auto-populate entries
router.post( "/populate", middlewareObj.isLoggedIn, function( req, res) {
  // Ensure req.body.orgs is an array
  var orgList=[]

  if (typeof req.body.orgs == 'string') {
    orgList = [req.body.orgs]
  } else {
    orgList = req.body.orgs
  };

  orgList.save

  //lookup Plan using ID
  Plan.findById( req.params.id, function(err, foundPlan){
    if(err){
      console.log( err);
      res.redirect("/plans");
    } else {
      BaseData.find({
        "contributingRegion": foundPlan.contributingRegion,
        "org": { $in: orgList}
      }, function( err, baseData) {
        if (err) {
          console.log( err)
        } else {
          // console.log( baseData.length);

          //Loop through baseData to create entries & push into plan
          async.eachSeries( baseData, function(data, next) {
            console.log(data);
            // Create new entry record
            var entry = new Entry({
              author: {
                id: req.user._id,
                username: req.user.username
              },
              org: data.org,
              jobFamily: data.jobFamily,
              globalGrade: data.globalGrade,
              location: data.location,
              initHC: data.initHC,
              initResRate: data.initResRate.toFixed(3)
            });

            // Derive calculated variables for entry
            entry.adjHC                  = entry.initHC;
            entry.adjResRate             = entry.initResRate;
            entry.yr1Resignations        = Math.round(entry.adjHC * entry.adjResRate);
            entry.yr1Supply              = entry.adjHC - entry.yr1Resignations;
            entry.yr2Resignations        = Math.round(entry.yr1Supply * entry.adjResRate);
            entry.yr2Supply              = entry.yr1Supply - entry.yr2Resignations;
            entry.yr3Resignations        = Math.round(entry.yr2Supply * entry.adjResRate);
            entry.yr3Supply              = entry.yr2Supply - entry.yr3Resignations;
            entry.yr4Resignations        = Math.round(entry.yr3Supply * entry.adjResRate);
            entry.yr4Supply              = entry.yr3Supply - entry.yr4Resignations;
            entry.yr5Resignations        = Math.round(entry.yr4Supply * entry.adjResRate);
            entry.yr5Supply              = entry.yr4Supply- entry.yr5Resignations;
            entry.demandYr0              = entry.adjHC;
            entry.demandYr1              = entry.adjHC;
            entry.demandYr2              = entry.adjHC;
            entry.demandYr3              = entry.adjHC;
            entry.demandYr4              = entry.adjHC;
            entry.demandYr5              = entry.adjHC;
            entry.gapYr1                 = entry.yr1Supply - entry.demandYr1;
            entry.gapYr2                 = entry.yr2Supply - entry.demandYr2;
            entry.gapYr3                 = entry.yr3Supply - entry.demandYr3;
            entry.gapYr4                 = entry.yr4Supply - entry.demandYr4;
            entry.gapYr5                 = entry.yr5Supply - entry.demandYr5;
            entry.save();

            // Push entry into plan
            foundPlan.planEntries.push(entry);
            foundPlan.save(function(err){
              if (err) {
                console.log(err)
              } else{
                entry = {}
                // next iteration
                next()
              };
            });

          }, function(err) {
            // This function runs when all iterations are done
            if (err) throw err;
            res.redirect('/plans/' + foundPlan._id);
          } );  /*End of Async Loop*/
        };
      });     /*End of BaseDate.find*/
    }         
  });         /*End of Plan.findById*/
});

// =====================================================
// ======UPDATE ENTRIES FROM SUPPLY/DEMAND SCREENS======
// =====================================================

// Entry Update (from Supply Screen)
router.put("/:entryId", middlewareObj.isLoggedIn, function(req, res){
    // console.log(req.body)
    var adjHC                  = req.body.entry.adjHC;
    var adjResRate             = req.body.entry.adjResRate / 100;
    var yr1Resignations        = Math.round(adjHC * adjResRate);
    var yr1Supply              = adjHC - yr1Resignations;
    var yr2Resignations        = Math.round(yr1Supply * adjResRate);
    var yr2Supply              = yr1Supply - yr2Resignations;
    var yr3Resignations        = Math.round(yr2Supply * adjResRate);
    var yr3Supply              = yr2Supply - yr3Resignations;
    var yr4Resignations        = Math.round(yr3Supply * adjResRate);
    var yr4Supply              = yr3Supply - yr4Resignations;
    var yr5Resignations        = Math.round(yr4Supply * adjResRate);
    var yr5Supply              = yr4Supply- yr5Resignations;
    var demandYr0              = adjHC;
    var demandYr1              = adjHC;
    var demandYr2              = adjHC;
    var demandYr3              = adjHC;
    var demandYr4              = adjHC;
    var demandYr5              = adjHC;
    var gapYr1                 = yr1Supply - demandYr1;
    var gapYr2                 = yr2Supply - demandYr2;
    var gapYr3                 = yr3Supply - demandYr3;
    var gapYr4                 = yr4Supply - demandYr4;
    var gapYr5                 = yr5Supply - demandYr5;

    var updatedEntry = {adjHC           : adjHC, 
                        adjResRate      : adjResRate,
                        yr1Resignations : yr1Resignations,
                        yr2Resignations : yr2Resignations,
                        yr3Resignations : yr3Resignations,
                        yr4Resignations : yr4Resignations,
                        yr5Resignations : yr5Resignations,
                        yr1Supply       : yr1Supply,
                        yr2Supply       : yr2Supply,
                        yr3Supply       : yr3Supply,
                        yr4Supply       : yr4Supply,
                        yr5Supply       : yr5Supply,
                        demandYr0       : demandYr0,
                        demandYr1       : demandYr1,
                        demandYr2       : demandYr2,
                        demandYr3       : demandYr3,
                        demandYr4       : demandYr4,
                        demandYr5       : demandYr5,
                        gapYr1          : gapYr1,
                        gapYr2          : gapYr2,
                        gapYr3          : gapYr3,
                        gapYr4          : gapYr4,
                        gapYr5          : gapYr5            };

   //lookup Entry using ID
    Entry.findByIdAndUpdate(req.params.entryId, updatedEntry, {new: true}, function(err, foundEntry){
       if(err){
            console.log(err);
            res.redirect("/plans");
       } else {
            res.json(foundEntry);
        }
    });
});