sql >> データベース >  >> NoSQL >> MongoDB

条件付きの既存のフィールドからスコアを計算します

    実装にはいくつかの問題があります。まず、 find()を使用しています クエリに指定する引数が多すぎるため、メソッドが正しくありません:

    MyModel.find(
        { Mkt_Al : Mkt_Air }, 
        { Orig : Origin }, 
        { Dest : Thru_Point }, 
        { Eff_Date : Effective_Date }
    ).lean().exec(function(err, docs) { .. }
    

    する必要があります

    MyModel.find({ 
        Mkt_Al: Mkt_Air, 
        Orig: Origin, 
        Dest: Thru_Point, 
        Eff_Date: Effective_Date 
    }).lean().exec(function(err, docs) { ... }
    

    繰り返しになりますが、 find()<を使用しないでください。 / code> この場合のメソッドは、計算で使用するクエリに一致する単一のドキュメントのみが必要なためです。前の閉じた質問から複雑なアルゴリズムを取得します:

    MyModel.findOne()の使用 上記のタスク3、4、および5には十分です。ただし、呼び出しは非同期であるため、クエリをネストする必要がありますが、ネストされた呼び出しの深さは3以下です。そうしないと、CallbackHellへの片道切符を手に入れることになります。これらの一般的な落とし穴を回避するには、 Promises (ネイティブのマングースクエリはデフォルトで Promise> )または node-asyncを使用します このような状況に対処するための多くの機能を含むパッケージ。

    asyncを使用する場合 ライブラリを使用すると、複数の非同期タスク( MyModel.findOne()など)を効率的に実行できます。 呼び出し)は互いに依存し、それらがすべて終了したときに何か他のことをします。上記では、 async.series() メソッド。

    次の例は、 Qsiを計算できる上記の概念を示しています。 テストデータベースの次のサンプルドキュメントから。

    テストデータベースのボリュームコレクションにデータを入力する:

    db.vols.insert([
        {    
            "Mkt_Al" : "2G",
            "Stops" : 0,
            "Seats" : 169,
            "Block_Mins" : 230,                
            "Ops_Week" : 3,        
            "Orig" : "AGP",
            "Dest" : "OTP",
            "Thru_Point" : "",
        },
        {    
            "Mkt_Al" : "2G",
            "Stops" : 1,
            "Seats" : 260,              
            "Block_Mins" : 260,
            "Ops_Week" : 2,  
            "Orig" : "CEK",
            "Dest" : "IKT",
            "Thru_Point" : "OVB",
        },
        {    
            "Mkt_Al" : "2G",
            "Stops" : 0,
            "Seats" : 140,
            "Block_Mins" : 60,
            "Ops_Week" : 2,        
            "Orig" : "BEK",
            "Dest" : "OTP",
            "Thru_Point" : "",
        },
        {    
            "Mkt_Al" : "2G",
            "Stops" : 0,
            "Seats" : 160,
            "Block_Mins" : 90,
            "Ops_Week" : 3,        
            "Orig" : "CEK",
            "Dest" : "OVB",
            "Thru_Point" : "",
        },
        {    
            "Mkt_Al" : "2G",        
            "Stops" : 0,
            "Seats" : 60,
            "Block_Mins" : 50,
            "Ops_Week" : 3,        
            "Orig" : "OVB",
            "Dest" : "IKT",
            "Thru_Point" : "",
        }
    ])
    

    Node.jsアプリ:

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

    サンプル出力:

    db.vols.find()
    
    /* 1 */
    {
        "_id" : ObjectId("5767e7549ebce6d574702221"),
        "Mkt_Al" : "2G",
        "Stops" : 0,
        "Seats" : 169,
        "Block_Mins" : 230,
        "Ops_Week" : 3,
        "Orig" : "AGP",
        "Dest" : "OTP",
        "Thru_Point" : "",
        "Qsi" : 3.42018
    }
    
    /* 2 */
    {
        "_id" : ObjectId("5767e7549ebce6d574702222"),
        "Mkt_Al" : "2G",
        "Stops" : 1,
        "Seats" : 260,
        "Block_Mins" : 260,
        "Ops_Week" : 2,
        "Orig" : "CEK",
        "Dest" : "IKT",
        "Thru_Point" : "OVB",
        "Qsi" : 3.1064
    }
    
    /* 3 */
    {
        "_id" : ObjectId("5767e7549ebce6d574702223"),
        "Mkt_Al" : "2G",
        "Stops" : 0,
        "Seats" : 140,
        "Block_Mins" : 60,
        "Ops_Week" : 2,
        "Orig" : "BEK",
        "Dest" : "OTP",
        "Thru_Point" : "",
        "Qsi" : 2.0168
    }
    
    /* 4 */
    {
        "_id" : ObjectId("5767e7549ebce6d574702224"),
        "Mkt_Al" : "2G",
        "Stops" : 0,
        "Seats" : 160,
        "Block_Mins" : 90,
        "Ops_Week" : 3,
        "Orig" : "CEK",
        "Dest" : "OVB",
        "Thru_Point" : "",
        "Qsi" : 3.2976
    }
    
    /* 5 */
    {
        "_id" : ObjectId("5767e7549ebce6d574702225"),
        "Mkt_Al" : "2G",
        "Stops" : 0,
        "Seats" : 60,
        "Block_Mins" : 50,
        "Ops_Week" : 3,
        "Orig" : "OVB",
        "Dest" : "IKT",
        "Thru_Point" : "",
        "Qsi" : 1.9356
    }
    


    1. express html-pdfパッケージを使用しているときに、画像が動的画像パスからレンダリングされない

    2. MongoDBを使用してプライベートメッセージングシステムを追跡する方法は?

    3. 公式C#ドライバーを使用したMongoDBでのアップサーティング

    4. 文字列_idとupsertを持つMongoimportcsvファイル