我想知道是否有人能帮我把聚合函数弄对。我正试图计算一条文本在指定日期内每小时出现的次数。到目前为止我有:

db.daily_data.aggregate(
  [
    { $project : { useragent: 1, datetime: 1, url: 1, hour: {$hour: new Date("$datetime")} } },
    { $match : { datetime: {$gte: 1361318400000, $lt: 1361404800000}, useragent: /.*LinkCheck by Siteimprove.*/i } },
    { $group : { _id : { useragent: "$useragent", hour: "$hour" }, queriesPerUseragent: {$sum: 1} } }
  ]
);

但我显然搞错了,因为小时总是0:
{
  "result" : [
    {
      "_id" : {
        "useragent" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.0) LinkCheck by Siteimprove.com",
        "hour" : 0
      },
      "queriesPerUseragent" : 94215
    }
  ],
  "ok" : 1
}

下面是一个精简的记录示例:
{
  "_id" : ObjectId("50fe63c70266a712e8663725"),
  "useragent" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.0) LinkCheck by Siteimprove.com",
  "datetime" : NumberLong("1358848954813"),
  "url" : "http://www.somewhere.com"
}

我也尝试过使用new Date("$datetime").getHours()而不是$hour函数来尝试获得相同的结果,但没有成功。有人能告诉我哪里出错了吗?
谢谢!

最佳答案

这是一个建议,而不是你的问题的答案。
在MongoDB for Analytics上,建议预先聚合要计算的每个度量的存储桶(用例中的每小时存储桶)。
因此,对于度量,您可以更新预聚合集合(加快查询时间):

db.user_agent_hourly.update({url: "your_url", useragent: "your user agent", hour: current_HOUR_of_DAY, date: current_DAY_Date}, {$inc: {counter:1}}, {upsert:true})

考虑到在current_DAY_Date中,您必须指向当前日期的稳定日期值,即当前年份/当前月份/当前日期00:00:00,对当前日期中收到的每个度量使用相同的小时:分钟:秒。
然后,您可以查询此集合,提取任意给定时间段的聚合分析,如下所示:
 db.user_agent_hourly.aggregate(
    {$match:{date:{$gte: INITIAL_DATE, $lt: FINAL_DATE}}},
    {$group:{ _id : { useragent: "$useragent", hour: "$hour" } ,queriesPerUseragent: {$sum: "$count"} } },
    {$sort:{queriesPerUseragent:-1}}
 )

如果要使用特定用户代理筛选结果,可以使用下一个查询:
 db.user_agent_hourly.aggregate(
    {$match:{date:{$gte: INITIAL_DATE, $lt: FINAL_DATE, useragent: "your_user_agent"}}},
    {$group:{ _id : { useragent: "$useragent", hour: "$hour" }, queriesPerUseragent: {$sum: "$count"} } }
 )

备注:我们将每个接收到的度量存储在其他集合中,以便在发生灾难或其他需要时重新处理它。

10-06 14:18
查看更多