1

我正在尝试在 mongo 聚合函数中按 DayHours 分组以获取过去 24 小时的数据。例如:如果事件的时间是星期五 6:00,则“DayHour”将是 6-5。我可以使用以下查询轻松地按小时分组:

db.api_log.aggregate([
    { '$group': { 
        '_id': { 
            '$hour': '$time'
        }, 
        'count': { 
          '$sum':1 
        } 
      } 
    },
    { '$sort' : { '_id': -1 } }
  ])

我觉得有更好的方法来做到这一点。我已经尝试在 $project 语句中进行连接,但是您只能在 mongo 中连接字符串(显然)。我实际上只需要按天和小时分组,但是它已经完成了。谢谢你。

4

2 回答 2

1

我假设该time字段包含ISODate. 如果你只想要最后 24 小时,你可以使用这个:

var yesterday = new Date((new Date).setDate(new Date().getDate() - 1));

db.api_log.aggregate(
    {$match: {time: {$gt: yesterday}}},
    {$group: {
        _id: {
            hour: {$hour: "$time"},
            day: {$dayOfMonth: "$time"},
        },
        count: {$sum: 1}
    }}
)          

如果你想按天小时进行一般分组,你可以使用这个:

db.api_log.aggregate(
    {$group: {
        _id: {
            hour: {$hour: "$time"},
            day: {$dayOfMonth: "$time"},
            month: {$month: "$time"},
            year: {$year: "$time"}
        },
        count: {$sum: 1}
    }}
)
于 2013-11-05T08:09:59.757 回答
0

这本身也不是一个答案(我现在没有 mongodb 来提供答案),但我认为你不能仅使用聚合框架来做到这一点(我可能错了,所以我会解释自己)。

您可以使用.getTimestamp方法从 mongoId 获取日期和时间信息。您无法在 mongo 查询中输出此信息的问题(类似db.find({},{_id.getTimestamp})不起作用)。您也不能按此字段搜索(使用$where子句除外)。

因此,如果可以实现,则只能使用 mapreduce 来完成,在 reduce 函数中,您可以根据getTimestamp.

如果这是您要经常执行的查询,我建议date您在文档中实际添加字段,因为使用此字段您将能够正确聚合您的数据,并且您可以使用 indeces 不扫描所有集合(就像您是用 $sort -1 做,但$match只做比current date-大的部分24 hours

我希望即使没有代码也能有所帮助。如果没有人能够回答这个问题,我明天会尝试玩它。

于 2013-11-05T07:26:36.433 回答