【问题标题】:Aggregation Framework on Date日期聚合框架
【发布时间】:2013-03-09 18:24:45
【问题描述】:

我正在尝试在 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

【问题讨论】:

    标签: node.js mongodb date aggregation-framework


    【解决方案1】:

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

    Stupid Date Tricks with Aggregation Framework.

    您可以在此处查看完整的分步细分,但总而言之,您有两个选择:

      1234563 YMD 到 {$group} 上。
    • 如果您确实关心分组值保持在 ISODate 您可以 {$subtract} 时间部分在 {$project} 阶段并留下 ISODate() 类型 - 需要注意的是此方法需要MongoDB 2.4 (just released) 添加了对日期算术和$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"}
        }   
      }
    ])
    

    【讨论】:

    • 谢谢,我会读的。我应该说,但我想按日期汇总,所以全年/月/日+小时和分钟。其余的我不关心。
    • 小时和分钟意味着您按分钟聚合 - 但将任一路径扩展到您想要的路径很简单。就像我说的,如果你在 2.2 上,那么使用第一种方式, {$project:{year:{$year:"$Date"}, month:{$month:"$Date"}, etc} 否则在你的已经抓到 2.4 我推荐在博文中使用 {$subtract} 来摆脱 $millisecond 部分的方式。
    • 我真的不明白这是怎么回事。我无法重现该示例并使其正常工作。
    • 您尝试了什么,错误是什么(或不正确的结果)?如果我确切地知道您在寻找什么,我很乐意帮助它纠正形式。首先,您使用的是哪个版本的 MongoDB,您尝试使用我描述的两种方法中的哪一种?
    【解决方案2】:

    如果不是 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"}
        }   
    }
    )
    

    【讨论】:

    • 我收到一个错误,$min 不存在,并且使用 $minute,我有“errmsg”:“异常:无法从 BSON 类型 OID 转换为日期”。无论如何,谢谢人:)
    • 你能把输入记录放到你的问题中吗?如果我们知道字段/类型,就更容易找到解决方案。
    • $min 不存在,但有 $minute 运算符。此外,他的日期存储在“日期”字段而不是_id。
    【解决方案3】:

    您现在可以使用 MongoDB 日期聚合运算符,我的博客上有一篇文章介绍了 Schema 设置,在 Node.js 中使用它等等:

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

    【讨论】:

      猜你喜欢
      • 2013-01-22
      • 1970-01-01
      • 1970-01-01
      • 2013-05-27
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 2021-02-05
      • 2017-12-28
      相关资源
      最近更新 更多