繁体   English   中英

如何进行查询以生成等效的日期范围并求和mongodb中的计数

[英]how to make query that can generate the equivalent date range and sum the count in mongodb

我正在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"), "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 }

在这里,我将给出开始时间和结束时间,然后我需要将停留时间的总和计算为每周一次,例如(第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" }
  }}

]);

或者,如果您希望在响应中使用时间戳记值(自epoch以来的毫秒数),则可以采用这种日期数学方法,而不是在星期初获取日期值:

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文档中的常规聚合管道运算符 ,以获取有关使用的每个运算符的详细说明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM