【问题标题】:How to use aggregate to group by half hour with rounding?如何使用聚合按半小时分组并四舍五入?
【发布时间】:2015-11-02 07:33:13
【问题描述】:

我正在使用$group 将我的帖子按小时分组,例如:

"$group" : {
    "_id" : {
        "$hour" : {
            $add : ["$createdAt", 10*60*60*1000]
        }
    },
    ...
}

但现在我也想按半小时分组,意思是:

2:30 => 3:00
2:29 => 2:00

我如何使用 mongo 聚合来解决这个问题? Sr 为我的英语不好。 :)

【问题讨论】:

    标签: mongodb sails.js mongodb-query aggregation-framework


    【解决方案1】:

    我在这里收集 +10 是为了调整时区。相同的基本原则适用于生成具有 30 分钟舍入的日期,除了您想首先转换为数值并通过模数 ($mod) 计算间隔:

        { "$group": {
            "_id": {
                "$add": [
                    { "$subtract": [
                        { "$subtract": [
                            { "$add": [ "$createdAt", 1000 * 60 * 60 * 10 ] },
                            new Date(0) 
                        ]},
                        { "$mod": [
                            { "$subtract": [
                                { "$add": [ "$createdAt", 1000 * 60 * 60 * 10 ] }, 
                                new Date(0)
                            ]},
                            1000 * 60 * 30
                        ]}
                    ]},
                    new Date(0)
                ]
            },
            "count": { "$sum": 1 } // or whatever accumulation required
        }}
    

    将纪元日期 (Date(0)) 与存储日期 (adjusted) 的 $subtract 操作结合使用,将从纪元开始的毫秒数作为存储日期的数值返回。对 30 分钟内的毫秒数进行取模运算会返回当前日期的余数,然后您再$subtract 再次获得一个舍入间隔。

    $add 操作也是如此,其中将纪元日期对象转换为数值再次返回 Date

    所以现在每个间隔开始都是分组键,从每 30 分钟开始。

    您可以交替使用日期聚合运算符,但这会返回一个 BSON Date 对象,该对象将在 API 中进行转换,而不仅仅是“分钟”间隔的数值。

    这只是标准的“日期数学”,所以所有相同的操作都适用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-04
      • 2021-03-25
      • 2021-09-30
      • 2023-01-12
      • 2018-06-17
      • 1970-01-01
      • 2013-07-03
      • 2016-04-13
      相关资源
      最近更新 更多