我有一个mongo文档,其中一些寄存器以日期存储,例如以非常简单的方式存储:
{
"vehicleId" : "vehicle4",
"telemetryDate" : ISODate("2013-06-22T05:00:00Z"),
"alarmsTotal" : 9
}
{
"vehicleId" : "vehicle5",
"telemetryDate" : ISODate("2013-06-20T05:00:00Z"),
"alarmsTotal" : 2
}
我需要通过vhicleId执行一个组,总计警报总数。不过,可以选择是否排除周末(周六,周日)。
我一直在寻找与Mongo这个问题无关的答案。我的查询,如果没有将排除周末纳入正常工作的帐户是:
{
"aggregate":"telemetrySummary",
"pipeline":[
{
"$match":{
"telemetryDate":{
"$gte":{
"$date":"2013-06-20T05:00:00.000Z"
},
"$lte":{
"$date":"2013-06-24T05:00:00.000Z"
}
}
}
},
{
"$group":{
"_id":{
"vehicleId":"$vehicleId"
},
"alarms":{
"$sum":"$alarmsTotal"
}
}
}
]
}
我需要排除mongo运算符$ dayOfWeek为1(星期日)和7(星期日)的值。我尝试了很多查询,其中一个逻辑是:
{
"aggregate":"telemetrySummary",
"pipeline":[
{
"$match":{
"telemetryDate":{
"$gte":{
"$date":"2013-06-20T05:00:00.000Z"
},
"$lte":{
"$date":"2013-06-24T05:00:00.000Z"
}
},
"{ \"$dayOfWeek\" : \"$telemetryDate\"}":{
"$in":[2,3,4,5,6]
}
}
},
{
"$group":{
"_id":{
"vehicleId":"$vehicleId"
},
"alarms":{
"$sum":"$alarmsTotal"
}
}
}
]
}
我认为我的真正问题基本上是我不知道如何将$ dayOfWeek操作存储在非grupable变量上作为telemetryDate到day变量中,我可以与$ in运算符进行比较。
感谢阅读并希望找到一些指导:)
答案 0 :(得分:3)
实际上这很简单 - 您可以使用$ project创建原始文档中不存在的新字段 - 您可以计算新值,也可以有条件地投影不同的值,具体取决于原始值。您甚至可以在单个组阶段计算总报警以及工作日仅报警。
以下是您在项目阶段需要做的事情:
{"$project" : {
"vehicleId" : 1,
"telemetryDate" : 1,
"alarmsTotal" : 1,
"alarmsWeekdays" : {
"$cond" : [
{
"$or" : [
{
"$eq" : [
{
"$dayOfWeek" : "$telemetryDate"
},
1
]
},
{
"$eq" : [
{
"$dayOfWeek" : "$telemetryDate"
},
7
]
}
]
},
0,
"$alarmsTotal"
]
}
}
}
上面说的是:“通过这三个领域,但也计算一个新的领域报警周末如此:......”
更多“英语”术语的实际表达恰好是:
IF `$dayOfWeek` of telemetryDate is equal to 1
OR `$dayOfWeek` of telemetryDate is equal to 7
THEN `$project` the value 0 as `alarmsWeekdays
ELSE `$project` the value from `$alarmsTotal` as `alarmsWeekdays`
答案 1 :(得分:2)
您应该在 $ project 中使用 $ dayOfWeek ,如下所示:
[{<your match by date>}, {$project:{vehicleId:1, telemetryDate:1, alarmsTotal:1, dow:{$dayOfWeek:'$telemetryDate'}}}, {$match:{dow:{$in:[2,3,4,5,6]}}}, <rest of pipeline> ]
btw ,您的第一个 $ match 可以从使用索引中受益,就像普通的查找命令一样。它将提高大型数据集的性能。