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);
}
});
});
在我的
// 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);
}
});
});