从存储带有时间戳的数据的MongoDB集合中,我需要为每小时返回一条记录。
到目前为止,我已成功选择了两个日期之间的记录集,但我无法确定如何在$group
子句中构建我需要的每小时记录。
var myName = "CollectionName"
//schema for mongoose
var mySchema = new Schema({
dt: Date,
value: Number
});
var myDB = mongoose.createConnection('mongodb://localhost:27017/MYDB');
myDBObj = myDB.model(myName, evalSchema, myName);
此聚合调用中的匹配工作正常,$hour
创建当天每小时的记录..但我不知道如何重新创建完整日期并获得错误{{1 } ...
"unknown group operator $avg"
我想我需要使用myDBObj.aggregate([
{
$match: { "dt": { $gt: new Date("October 13, 2010 12:00:00"), $lt: new Date("November 13, 2010 12:00:00") } }
},{
$group: {
"_id": { "dt": { "$hour": "$dt" } , "price": { "$avg": "$price" }}
}], function (err, data) { if (err) { return next(err); } res.json(data); });
因此每天每小时都有不同的记录,并在某处包含$dayOfYear
...
有人可以帮我正确地做到这一点吗?任何帮助表示赞赏。
答案 0 :(得分:1)
$group
管道阶段的工作原理是通过为_id
指定的“密钥”对所有数据进行“分组”。您实际聚合的其他字段与_id
值分开,并且是它们自己的字段属性。
所以你的$group
会改为:
{ "$group": {
"_id": { "$hour": "$dt" },
"price": { "$avg": "$price" }
}}
或者,如果您希望按天打破,那么请复制一下密钥:
{ "$group": {
"_id": {
"day": { "$dayOfYear": "$dt" },
"hour": { "$hour": "$dt" }
},
"price": { "$avg": "$price" }
}}
或者只使用日期数学来生成按小时舍入的Date
个对象:
{ "$group": {
"_id": {
"$add": [
{ "$subtract": [
{ "$subtract": [ "$dt", new Date(0) ] },
{ "$mod": [
{ "$subtract": [ "$dt", new Date(0) ] },
1000 * 60 *60
]}
]},
new Date(0)
]
},
"price": { "$avg": "$price" }
}}
如果将另一个日期对象(纪元日期)从另一个日期对象中生成一个数值,您可以使用应用的数学运算(1000毫秒,60秒,60分钟= 1小时),并向日期对象添加数字会生成日期对应于该值。
所以你的问题是_id
中的所有内容都无法识别$avg
累加器。需要在分组键之外指定所有累加器。这就是意图。
如果你想将累加器值作为分组键的一部分(虽然这里似乎没有相关性),而是使用另一个组阶段,引用从前者生成的字段。