MongoDB按小时分组

17

我将推文保存到MongoDB:

 twit.stream('statuses/filter', {'track': ['animal']}, function(stream) {
    stream.on('data', function(data) {
        console.log(util.inspect(data));

        data.created_at = new Date(data.created_at);
        collectionAnimal.insert(data, function(err, docs) {});
    });
});

没问题。

MongoDB中的推文时间格式为:2014-04-25 11:45:14 GMT(列名为created_at) 现在我需要按小时对列created_at进行分组。 我想要以下结果:

小时 | 每小时推文数量


1 | 28

2 | 26

3 | 32

4 | 42

5 | 36

...

我的尝试失败了:

    $keys = array('created_at' => true);
    $initial = array('count' => 0);
    $reduce = "function(doc, prev) { prev.count += 1 }";

    $tweetsGroup = $this->collectionAnimal->group( $keys, $initial, $reduce );

但我不能按小时分组。

该怎么做?


你能给我们展示一个你有的示例文档吗? - Sammaye
4个回答

30

我可以告诉你如何在Mongo控制台上直接使用聚合框架进行分组

db.tweets.aggregate(
 { "$project": {
      "y":{"$year":"$created_at"},
      "m":{"$month":"$created_at"},
      "d":{"$dayOfMonth":"$created_at"},
      "h":{"$hour":"$created_at"},
      "tweet":1 }
 },
 { "$group":{ 
       "_id": { "year":"$y","month":"$m","day":"$d","hour":"$h"},
       "total":{ "$sum": "$tweet"}
   }
 })

如果您想了解更多选项,请查看此处:http://docs.mongodb.org/manual/reference/operator/aggregation-date/

您还需要找到适当的方式来使用聚合框架,无论使用哪种编程语言。


11
这里不需要使用$project阶段,因为日期运算符函数可以直接在定义分组_id时在$group阶段中使用。这样可以避免为了获取结果而处理整个集合的情况:
另外,你只是在计数,所以简单地使用{"$sum": 1},其中定义一个不存在的字段导致了0的问题。
    $this->collection->aggregate(array(
        array(
            '$group' => array(
                "_id" => array( 
                    "y" => array( '$year' => '$created_at' ),
                    "m" => array( '$month' => '$created_at' ),
                    "d" => array( '$dayOfMonth' => '$created_at' ),
                    "h" => array( '$hour' => '$created_at' ),
                ),
                "total" => array( '$sum' => 1 ),
            ),
        )
    ));

如果需要的话,在管道的开头添加一个$match阶段以过滤日期。如果一天可接受作为输出,则只需在分组中定义$hour,这样可以减少工作集大小,从而实现更快速度。这可能是您想要做的事情。


6

Lalit提供的答案对我来说没有用,它一直给我零。 相反,我做了以下操作:

db.tweets.aggregate(
 { "$project": {
      "y":{"$year":"$created_at"},
      "m":{"$month":"$created_at"},
      "d":{"$dayOfMonth":"$created_at"},
      "h":{"$hour":"$created_at"},
      "tweet":1 }
 },
 { "$group":{ 
       "_id": { "year":"$y","month":"$m","day":"$d","hour":"$h"},
       'count':{$sum:1} 
   }
 })

'count':{$sum:1} 是唯一的不同之处。

可能会对像我这样新手的MongoDB有所帮助。


0

自从MongoDB 5.0(2021年)以来,您可以使用$dateTruncunit: 'hour'参数:

db.tweets.aggregate([
  {
    $project: {
      hour: { $dateTrunc: { date: "$created_at", unit: "hour" } },
    },
  },
  {
    $group: {
      _id: "$hour",
      count: { $sum: 1 },
    },
  },
])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接