0

我正在尝试在 Mongo 中按日期聚合数据,但我无法完全实现我想要的。现在,我正在使用这个:

db.aggregData.aggregate( { $group: {_id: "$Date".toString(),  
                                   tweets: { $sum: "$CrawledTweets"} } }, 
                         { $match:{ _id: {$gte: ISODate("2013-03-19T12:31:00.247Z") }}}, 
                         { $sort: {Date:-1} } 
                       )

结果是这样的:

"result" : [
                {
                        "_id" : ISODate("2013-03-19T12:50:00.641Z"),
                        "tweets" : 114
                },
                {
                        "_id" : ISODate("2013-03-19T12:45:00.631Z"),
                        "tweets" : 114
                },
                {
                        "_id" : ISODate("2013-03-19T12:55:00.640Z"),
                        "tweets" : 123
                },
                {
                        "_id" : ISODate("2013-03-19T12:40:00.628Z"),
                        "tweets" : 91
                    },
                {
                        "_id" : ISODate("2013-03-19T12:31:00.253Z"),
                        "tweets" : 43
                },
                {
                        "_id" : ISODate("2013-03-19T13:20:00.652Z"),
                        "tweets" : 125
                },
                {
                        "_id" : ISODate("2013-03-19T12:31:00.252Z"),
                        "tweets" : 30
                }
 ],
        "ok" : 1

它似乎可以完成这项工作,但经过进一步检查,我们发现存在重复:
ISODate("2013-03-19T12:31:00.253Z") 和 ISODate("2013-03-19T12:31:00.252Z") .
唯一改变的是 Z 之前的最后一位。

所以这是我的问题。这部分是什么?我该怎么做才能在聚合中忽略它?

先感谢您。

编辑:我想按日期汇总,所以全年/月/日+小时和分钟。其余的我不关心。

编辑:我的数据库在 mongolab,所以我在 2.2

好吧,我以另一种方式做到了:我将所有日期的秒/毫秒保存为 0。所以我可以保留一个简单的聚合,而不需要更多的代码服务器端,这要感谢 moment.js

4

3 回答 3

6

您正在尝试按“整个”日期聚合,换句话说,从 ISODate() 中删除时间,对吗?有几种方法可以做到这一点,我在我的博客上的帖子中详细描述了它们

聚合框架的愚蠢约会技巧

您可以在那里看到完整的分步细分,但总结一下,您有两个选择:

  • 如果您不关心聚合值是否为 anISODate()那么您可以使用{$year},{$month}和相中的{$dayOfMonth}运算符{$project}将 YMD 拉出然后 {$group} 。

  • 如果您确实关心分组值保持不变,ISODate您可以{$subtract}将时间部分留在{$project}阶段并保留ISODate()类型 - 需要注意的是,此方法需要 MongoDB 2.4 (刚刚发布),它增加了对日期算术和$millisecond运算符的支持(参见确切博客文章中的代码)。

这可能是您想要的:

db.aggregData.aggregate([
  { 
    $project:{ 
        CrawledTweets: 1,
        newDate: { 
            year:{$year:"$Date"}, 
            month: {$month:"$Date"}, 
            day: {$dayOfMonth:"$Date"}, 
            hour: {$hour: "$Date"}, 
            min: {$minute: "$Date"}
        }   
    }   
  },
  { 
    $group: {
        _id: "$newDate",
        tweets: { $sum: "$CrawledTweets"}
    }   
  }
])
于 2013-03-20T16:35:17.203 回答
1

You can now use the MongoDB date aggregation operators, I have a post on my blog that goes over the Schema setup, using it in Node.js, etc:

http://smyl.es/how-to-use-mongodb-date-aggregation-operators-in-node-js-with-mongoose-dayofmonth-dayofyear-dayofweek-etc/

于 2013-10-14T16:11:04.707 回答
1

如果不是 Mongo 专家,也不知道你的数据库字段,我会想出这样的东西。也许您可以在此基础上构建:

db.aggregData.aggregate(
{ 
    $project:{ 
        CrawledTweets: 1,
        groupedTime: { 
            year:{$year:"$_id"}, 
            month: {$month:"$_id"}, 
            day: {$dayOfMonth:"$_id"}, 
            hour: {$hour: "$_id"}, 
            min: {$minute: "$_id"}
        }   
    }   
},
{ 
    $group: {
        _id: { groupedTime: "$CrawledTweets" },
        tweets: { $sum: "$tweets"}
    }   
}
)
于 2013-03-21T10:22:52.783 回答