我有一个包含许多文档的集合,例如:
直接航班< => Stops == 0
&& Thru_Point == ""
{
"Orig" : "PTH",
"Dest" : "GMP",
"Flight" : 126,
"Stops" : 0,
"Seats" : 169,
"Ops_Week" : 3,
"Eff_Date" : "2016-04-14",
"Mkt_Al" : "XX",
"Thru_Point" : "",
"Arr_Time" : 1600,
"Block_Mins" : 230
}
带停止的航班< => Stops == 1
&& Thru_Point != ""
{
"Orig" : "CIM",
"Dest" : "LKR",
"Flight" : 7756,
"Stops" : 1,
"Seats" : 70,
"Ops_Week" : 2,
"Eff_Date" : "2016-04-11",
"Mkt_Al" : "YY",
"Thru_Point" : "BHU",
"Arr_Time" : 140,
"Block_Mins" : 345 // the elapsed time
}
每个文件都指的是一个航班,我试图计算每个文件的分数,但我有一个困难,就是当我有一个停止航班我应该计算缩短的时间,直接飞行它&# 39;很简单,经过的时间等于Block_Mins
中的值,但对于有停止的航班,我应计算从Orig
到Thru_Point
和{{1}的每个段的经过时间转到Thru_point
Dest
我试过这个算法,但我发现自己有相同的值,无论是停止还是直飞!我认为问题来自于mongoose.connection.on("open", function (err) {
if (err) throw err;
var bulkUpdateOps = Vol.collection.initializeUnorderedBulkOp(),
counter = 0;
Vol.find({}).lean().exec(function (err, docs) {
if (err) throw err;
var locals = {};
docs.forEach(function(doc) {
locals.c1 = 0.3728 + (0.00454 * doc.Seats);
locals.c3 = doc.Ops_Week;
if (doc.Stops == 1) {
async.series([
// Load doc with first leg first
function(callback) {
Vol.findOne({
Mkt_Al: doc.Mkt_Al,
Orig: doc.Orig,
Dest: doc.Thru_Point
}).lean().exec(function (err, flight) {
if (err) return callback(err);
locals.first_leg = flight.Block_Mins;
callback();
});
},
// Load second leg doc
// (won't be called before task 1's "task callback"
// has been called)
function(callback) {
Vol.findOne({
Mkt_Al: doc.Mkt_Al,
Orig: doc.Thru_Point,
Dest: doc.Dest
}).lean().exec(function (err, flight) {
if (err) return callback(err);
locals.second_leg = flight.Block_Mins;
callback();
});
}
], function(err) { // This function gets called after the
// two tasks have called their "task callbacks"
if (err) throw err;
// Here locals will be populated with `first_leg`
// and `second_leg`
// Just like in the previous example
var total_flight = locals.second_leg + locals.first_leg;
locals.c2 = 0.03;
locals.c4 = Math.pow((doc.Block_Mins / total_flight), -0.675);
});
} else {
locals.c2 = 1;
locals.c4 = 1;
}
counter++;
console.log(locals);
bulkUpdateOps.find({ "_id" : doc._id }).updateOne({
"$set": {
"Qsi": (locals.c1 * locals.c2 * locals.c3 * locals.c4)
}
});
if (counter % 500 == 0) {
bulkUpdateOps.execute(function(err, result) {
if (err) throw err;
bulkUpdateOps = Vol.collection.initializeUnorderedBulkOp();
});
}
});
if (counter % 500 != 0) {
bulkUpdateOps.execute(function(err, result) {
if (err) throw err;
console.log(result.nModified);
});
}
});
});
或async.series
在其他任务之后也应该在bulkupdate
中取代......
提前谢谢你;
答案 0 :(得分:0)
不保证Async.series按照声明的顺序运行。 每async.js documentation:
请注意,虽然许多实现保留了对象属性的顺序,但ECMAScript语言规范明确指出
未指定枚举属性的机制和顺序。
因此,如果您依赖于执行一系列函数的顺序,并希望它在所有平台上都能运行,请考虑使用数组。
您可以使用async.waterfall()
代替,这在您使用的情况下非常有意义。通过对代码进行微调,您可以进行此更改。这是一个例子:
(...)
docs.forEach(function(doc) {
locals.c1 = 0.3728 + (0.00454 * doc.Seats);
locals.c3 = doc.Ops_Week;
if (doc.Stops == 1) {
async.waterfall([
// Load doc with first leg first
function(callback) {
Vol.findOne({
Mkt_Al: doc.Mkt_Al,
Orig: doc.Orig,
Dest: doc.Thru_Point
}).lean().exec(function (err, flight) {
if (err) return callback(err);
// locals.first_leg = flight.Block_Mins; //no need to save it in locals variable.
callback(null, flight.Block_Mins); //passing "first_leg" forward to next function
});
},
// Load second leg doc
// (won't be called before task 1's "task callback"
// has been called)
function(first_leg, callback) {
Vol.findOne({
Mkt_Al: doc.Mkt_Al,
Orig: doc.Thru_Point,
Dest: doc.Dest
}).lean().exec(function (err, flight) {
if (err) return callback(err);
// locals.second_leg = flight.Block_Mins; //same as first leg. No need to save it in a local variable
callback(null, first_leg+flight.Block_Mins); //passing "total_flight" forward to next function
});
}
], function(err, total_flight) { // This function gets called after the
if (err) throw err;
locals.c2 = 0.03;
locals.c4 = Math.pow((doc.Block_Mins / total_flight), -0.675);
});
} else {
(...)