- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用 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
在每条路线( Origin
- Destination
)中都有一个 score
如何计算分数?
因此,我需要进行这些计算并将新字段“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
上,如果我在这条指令中丢失了数据...,我的 score
在 Stops = 0
,但如果 Stops = 1
,我的分数取值为 Nan
,并且在像 callback(null, docs)
请问谁能帮忙??
我怎样才能实现上述目标?
最佳答案
您的实现存在多个问题。首先,您使用的是 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()
方法,因为您只需要一个与查询匹配的文档即可用于您的计算。从您之前关闭的问题中提取复杂的算法:
Now I want to calculate a score
c4
and insert it into my collection :To do that I should calculate a value
c4
just like this :1) First I verify for each document if
( Field2 == 1 )
if it's true I continue else it's simplec4
takes value 1.2) Then I should make a loop "for" and see which document verify these conditions :
doc.Field1 == this.Field1 && doc.Field6 == this.Field6 &&
doc.Field7 == this.Field83) Then I take
doc.Field4
wich will be added to another document'sField4
4) I continue and I make another loop and look for another document wich verify these conditions :
it should have the same
Field1
just like the previous document and itsField6
equal to the previous documentField7
and itsField8
the same as Field8 in the first document5) Then I take
doc.Field4
and add it to the previousdoc.Field4
使用 MyModel.findOne()
应该足以完成上面的任务 3、4 和 5。但是,由于调用的异步性质,您需要嵌套查询,但幸运的是嵌套调用的深度不超过 3,否则您会发现自己有一张通往回调 hell 的单程票。为了避免这些常见的陷阱,最好使用 Promises
(因为默认情况下 native Mongoose 查询可以返回 Promise
)或使用 node-async
包,其中包含许多用于处理此类情况的函数。
如果使用 async
库,它允许您高效地运行多个相互依赖的异步任务(如 MyModel.findOne()
调用),当它们全部完成时执行其他操作。在上面,您可以使用 async.series()
方法。
以下示例演示了上述概念,您可以在其中根据测试数据库中的以下示例文档计算 Qsi
。
填充测试数据库的 vol 集合:
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
}
关于node.js - 根据条件从现有字段计算分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37791777/
我正在努力处理查询的 WHERE 部分。查询本身包含一个基于两个表中都存在的 ID 的 LEFT JOIN。但是,我要求 where 语句仅返回其中一列中存在的最大单个结果。目前我返回连接中的所有值,
我有这个代码来改变文件系统的大小。问题是,即使满足 if 条件,它也不会进入 if 条件,而我根本没有检查 if 条件。它直接进入 else 条件。 运行代码后的结果 post-install-ray
假设我有一个包含 2 列的 Excel 表格:单元格 A1 到 A10 中的日期和 B1 到 B10 中的值。 我想对五月日期的所有值求和。我有3种可能性: {=SUM((MONTH(A1:A10)=
伪代码: SELECT * FROM 'table' WHERE ('date' row.date 或 ,我们在Stack Overflow上找到一个类似的问题: https://stackove
我有下面这行代码做一个简单的查询 if ($this->fulfilled) $criteria->addCondition('fulfilled ' . (($this->fulfilled
如果在数据库中找到用户输入的键,我将尝试显示“表”中的数据。目前我已将其设置为让数据库检查 key 是否存在,如下所示: //Select all from table if a key entry
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 5 年前。 Improve th
在MYSQL中可以吗 一共有三个表 任务(task_id、task_status、...) tasks_assigned_to(ta_id、task_id、user_id) task_suggeste
我想先根据用户的状态然后根据用户名来排序我的 sql 请求。该状态由 user_type 列设置: 1=活跃,2=不活跃,3=创始人。 我会使用此请求来执行此操作,但它不起作用,因为我想在“活跃”成员
下面两个函数中最专业的代码风格是什么? 如果函数变得更复杂和更大,例如有 20 个检查怎么办? 注意:每次检查后我都需要做一些事情,所以我不能将所有内容连接到一个 if 语句中,例如: if (veh
我在 C# 项目中使用 EntityFramework 6.1.3 和 SQL Server。我有两个查询,基本上应该执行相同的操作。 1. Exams.GroupBy(x=>x.SubjectID)
我试图在 case when 语句中放入两个条件,但我在 postgresql 中遇到语法错误 case when condition 1 and condition 2 then X else Y
我正在构建一个连接多个表的查询,一个表 prodRecipe 将包含某些行的数据,但不是全部,但是 tmp_inv1 将包含所有行的计数信息。问题是,tmp_inv1.count 取决于某个项目是否在
我有一个涉及 couples of rows which have a less-than-2-hours time-difference 的查询(~0.08333 天): SELECT mt1.*,
我有一个包含许多这样的 OR 条件的代码(工作正常)来检查其中一个值是否为空,然后我们抛出一条错误消息(所有这些都必须填写) } elsif ( !$params{'account'}
我有一个名为 spGetOrders 的存储过程,它接受一些参数:@startdate 和 @enddate。这将查询“订单”表。表中的一列称为“ClosedDate”。如果订单尚未关闭,则此列将保留
在代码中,注释部分是我需要解决的问题...有没有办法在 LINQ 中编写这样的查询?我需要这个,因为我需要根据状态进行排序。 var result = ( from contact in d
我正在尝试创建一个允许省略参数的存储过程,但如果提供了参数,则进行 AND 操作: CREATE PROCEDURE MyProcedure @LastName Varchar(30)
我正在寻找一种方法来过滤我的主机文件中的新 IP 地址。我创建了一个脚本,每次我用来自矩阵企业管理器的数据调用它时都会更新我的主机文件。它工作正常。但是我必须找到一个解决方案,只允许更新 10.XX.
所以我正在做一种 slider ,当它完全向下时隐藏向下按钮,反之亦然,当向上按钮隐藏时,我遇到了问题。 var amount = $('slide').attr('number'); $('span
我是一名优秀的程序员,十分优秀!