【发布时间】:2016-10-13 23:47:51
【问题描述】:
我正在开发 MongoDB 2.6.9 和 NodeJs 0.10.37,我有一个集合 vols,这意味着航班。
> db.vols.findOne()
{
"_id" : ObjectId("5717a5d4578f3f2556f300f2"),
"Orig" : "AGP",
"Dest" : "OTP",
"Flight" : 126,
"Routing" : "AGP-OTP",
"Stops" : 0,
"Seats" : 169,
"Ops_Week" : 3,
"Eff_Date" : "2016-04-14",
"Mkt_Al" : "0B",
"Dep_Time" : 1110,
"Thru_Point" : "",
"Arr_Time" : 1600,
"Block_Mins" : 230
}
每个文档指的是航空公司完成的一次航班,并提供了详细信息,例如,上一个文档指的是直接完成的航班(Stops : 0)。但是下一个,航班停了。
db.vols.findOne({Stops:1})
{
"_id" : ObjectId("5717a5d4578f3f2556f301c5"),
"Orig" : "CEK",
"Dest" : "IKT",
"Flight" : 7756,
"Routing" : "KZN-CEK-OVB-IKT",
"Stops" : 1,
"Seats" : 70,
"Ops_Week" : 2,
"Eff_Date" : "2016-04-11",
"Mkt_Al" : "2G",
"Dep_Time" : 1655,
"Thru_Point" : "OVB",
"Arr_Time" : 140,
"Block_Mins" : 345
}
重要:
每个Airline 在每条路线中都有一个score (Origin - Destination)
如何计算分数?
所以,我需要进行这些计算并将一个新字段“QSI”插入我的集合vols。
重要:
c4 中的平均经过时间意味着:
例如,我们有一个停止的航班,比如说:从 A 到 C 的航班由 B,整个航班例如60 分钟,但从 A 到 B 为 20 分钟,从 B 到 C 为 20 分钟,这个平均值应该返回 40 分钟。
我尝试了这个解决方案,但是对于 c4,事情看起来不像是什么工作:
var mongoose = require('mongoose'),
express = require('express'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/ramtest');
var volsSchema = new Schema({}, { strict : false, collection : 'vols' });
var MyModel = mongoose.model("MyModel", volsSchema);
mongoose.set('debug', true);
mongoose.connection.on("open", function(err) {
if (err) throw err;
var bulkUpdateOps = MyModel.collection.initializeUnorderedBulkOp(),
counter = 0;
MyModel.find({}).lean().exec(function(err, docs) {
if (err) throw err;
docs.forEach(function(doc) {
// computations
var c1, c2, c3, c4, qsi, first_leg, second_leg, total_flight;
c1 = 0.3728 + (0.00454 * doc.Seats);
c2 = (doc.Stops == 1) ? 0.03 : 1;
c3 = doc.Ops_Week;
if (doc.Stops == 1) {
var Mkt_Air = doc.Mkt_Al,
Origin = doc.Orig,
Destination = doc.Dest,
Thru_Point = doc.Thru_Point,
Effective_Date = doc.Eff_Date,
Block_Mins = doc.Block_Mins;
MyModel.find({ Mkt_Al : Mkt_Air }, { Orig : Origin }, { Dest : Thru_Point }, { Eff_Date : Effective_Date }).lean().exec(function(err, docs) {
docs.forEach(function(doc) {
var first_leg = doc.Block_Mins;
MyModel.find({ Mkt_Al : Mkt_Air }, { Orig : Thru_Point }, { Dest : Destination }, { Eff_Date : Effective_Date }).lean().exec(function(err, docs) {
docs.forEach(function(doc) {
var second_leg = doc.Block_Mins, total_flight = second_leg + first_leg;
c4 = Math.pow((Block_Mins / total_flight), -0.675);
qsi = c1 * c2 * c3 * c4;
}); // the end of docs.forEach(function (doc){
}); // the end of MyModel.find..
}); // the end of docs.forEach(function (doc){
}); // the end of MyModel.find..
} // end if
else {
c4 = 1;
}
qsi = c1 * c2 * c3 * c4;
counter++;
bulkUpdateOps.find({ "_id" : doc._id }).updateOne({
"$set" : { "Qsi" : qsi }
});
if (counter % 500 == 0) {
bulkUpdateOps.execute(function(err, result) {
if (err) throw err;
bulkUpdateOps = MyModel.collection.initializeUnorderedBulkOp();
console.log(result);
console.log(doc);
});
}
});
if (counter % 500 != 0) {
bulkUpdateOps.execute(function(err, result) {
if (err) throw err;
console.log(result);
});
}
});
var app = express();
app.listen(3000, function() {
console.log('Ready to calculate and insert the QSI');
});
});
问题:
我认为问题出在MyModel.find 上,比如如果我在这条指令中丢失数据...,当Stops = 0 时,我的score 计算干净,但如果Stops = 1,我的分数取值为@987654338 @,在像 callback(null, docs) 这样的一些迭代之后我有一个错误,请谁能帮忙??
我怎样才能达到上述目的?
【问题讨论】:
-
能否请您改进格式。很难遵循缩进。
-
我现在试着说得太清楚了......
-
@JeanDupont 我冒昧地为您重新格式化。
-
@robertklep 非常感谢
标签: node.js mongodb mongoose mongodb-query