Ruby on rails 如何在mongodb中进行查询,生成等价的日期范围和合计计数
我在Ruby on Rails语言中使用MONGODB,我有下表:Ruby on rails 如何在mongodb中进行查询,生成等价的日期范围和合计计数,ruby-on-rails,mongodb,mongoid,aggregation-framework,Ruby On Rails,Mongodb,Mongoid,Aggregation Framework,我在Ruby on Rails语言中使用MONGODB,我有下表: { "_id" : ObjectId("53d23cb06b69720326e80300"), "starttime" : ISODate("2014-07-24T10:14:04.809Z"), "endtime" : ISODate("2014-07-24T10:02:03.411Z"), "visitor_detail_id" : ObjectId("53cf8b686b697275230f0000"), "stayed
{ "_id" : ObjectId("53d23cb06b69720326e80300"), "starttime" : ISODate("2014-07-24T10:14:04.809Z"), "endtime" : ISODate("2014-07-24T10:02:03.411Z"), "visitor_detail_id" : ObjectId("53cf8b686b697275230f0000"), "stayedtime" : 721.398 }
{ "_id" : ObjectId("53d23cb06b69720326f20300"), "starttime" : ISODate("2014-07-24T09:48:04.595Z"), "endtime" : ISODate("2014-07-24T09:43:04.353Z"), "visitor_detail_id" : ObjectId("53cf8b686b697275230c0000"), "stayedtime" : 300.242 }
{ "_id" : ObjectId("53d23cb06b69720326f30300"), "starttime" : ISODate("2014-07-24T09:48:04.595Z"), "endtime" : ISODate("2014-07-24T09:43:04.353Z"), "visitor_detail_id" : ObjectId("53cf8b686b697275230c0000"), "stayedtime" : 300.242 }
{ "_id" : ObjectId("53d23cb06b69720326ed0300"), "starttime" : ISODate("2014-07-24T09:45:04.368Z"), "endtime" : ISODate("2014-07-24T09:33:04.281Z"), "visitor_detail_id" : ObjectId("53cf8b686b697275230c0000"), "stayedtime" : 720.087 }
在这里,我将给出starttime和endtime,然后我需要按周计算stayedtime的总和,如(第1周、第2周、第3周、第4周等)
我希望能够像这样生成:
| period | stayedtime |
| 1/7 - 7/5 | 2000 |
| 25/6 - 31/7 | .... |
| 18/6 - 24/6 | .... |
| 12/6 - 18/6 | .... |
MongoDB聚合框架具有多种功能,可以从日期中提取信息。您可以通过使用的类模型上的
.collection()
访问器从mongoid使用聚合框架:
result = Model.collection.aggregate([
# Query to match documents
{ "$match" => {
"starttime" => {
"$gte" => starttime, "$lte" => endtime
}
}},
# Group by intervals
{ "$group" => {
"_id" => {
"year" => { "$year" => "$endtime" },
"week" => { "$week" => "$endtime" }
},
"stayedtime" => { "$sum" => "$stayedtime" }
}}
]);
或者,如果您更喜欢在响应中使用时间戳值(自历元起的毫秒),您可以采用此日期数学方法,而不是在一周开始时获取日期值:
result = Model.collection.aggregate([
# Query to match documents
{ "$match" => {
"starttime" => {
"$gte" => starttime, "$lte" => endtime
}
}},
# Group by intervals
{ "$group" => {
"_id" => {
"$subtract" => [
{ "$subtract" => [
{ "$subtract" => [ "$endtime", Time.gm(1970,1,1) ] },
{ "$cond" => [
{ "$eq" => [ { "$dayOfWeek" => "$endtime" }, 1 ] },
0,
{ "$multiply" => [
1000 * 60 * 60 * 24,
{ "$subtract" => [ { "$dayOfWeek" => "$endtime" }, 1 ] }
]}
]}
]},
{ "$mod" => [
{ "$subtract" => [
{ "$subtract" => [ "$endtime", Time.gm(1970,1,1) ] },
{ "$cond" => [
{ "$eq" => [ { "$dayOfWeek" => "$endtime" }, 1 ] },
0,
{ "$multiply" => [
1000 * 60 * 60 * 24,
{ "$subtract": [ { "$dayOfWeek" => "$endtime" }, 1 ] }
]}
]}
]}
]}
]
},
"stayedtime" => { "$sum" => "$stayedtime" }
}}
])
在这两种情况下,“一周的开始”通常被认为是“星期天”,因此如果你打算从不同的一天开始作为“开始”工作,那么你需要调整你的数学
这会将“聚合”移动到服务器,您唯一的其他选项是在客户端代码中处理查询结果。一般来说,服务器将更快地完成这项工作,并避免为了进行处理而“在线”传输集合中的所有匹配文档
另请参阅官方MongoDB文档中的概述,以了解所使用的每个运算符的详细说明。您的
starttime
似乎发生在endtime
之后?