Node.js模块async.series无法正常工作

时间:2016-06-26 18:27:45

标签: asynchronous mongodb-query async.js

我正在使用MongoDB 2.6.9和NodeJs 0.10.37,我有一个收集卷,这意味着航班。

根据我之前的question,我有一个大型集合vols,其中包含以下文档:

> db.vols.findOne()
{
    "_id" : ObjectId("5717a5d4578f3f2556f300f2"),
    "Orig" : "PTH",
    "Dest" : "GMP",
    "Flight" : 126,
    "Stops" : 0,
    "Seats" : 169,
    "Ops_Week" : 3,
    "Eff_Date" : "2016-04-14",
    "Mkt_Al" : "XX",
    "Dep_Time" : 1110,
    "Thru_Point" : "",
    "Arr_Time" : 1600,
    "Block_Mins" : 230

}

下一份文件是指停止的航班。

> db.vols.findOne({Stops:1})
{
    "_id" : ObjectId("5717a5d4578f3f2556f301c5"),
    "Orig" : "CIM",
    "Dest" : "LKR",
    "Flight" : 7756,
    "Stops" : 1,
    "Seats" : 70,
    "Ops_Week" : 2,
    "Eff_Date" : "2016-04-11",
    "Mkt_Al" : "YY",
    "Dep_Time" : 1655,
    "Thru_Point" : "BHU",
    "Arr_Time" : 140,
    "Block_Mins" : 345
}

我必须使用此公式计算得分for each document,并将其作为新字段插入到文档中:

enter image description here

我尝试过这个算法,使用'async'模块和series方法,但我没有得到理想的结果......

var mongoose = require('mongoose'),
    express = require('express'),
    async = require('async'),
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');
var volSchema = new Schema({},{ strict: false, collection: 'vols' }),    
    Vol = mongoose.model("Vol", volSchema);

mongoose.set('debug', false);

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);                
            });
        }   
    });
});

最后,我发现自己的结果在两种情况下均相同,停止

我认为计算第二条腿的secend任务,等到所有first_legs的计算,而不是每个first_leg之后。

此外,分数的插入必须等到计算每个文档的分数结束时,我认为bulkinsert应该在其他计算之后进行。

现在我不知道我是否应该使用 async.series async.foreach async.parralel 或组合他们......

请谁能帮助实现上述目标......

0 个答案:

没有答案