【问题标题】:MongoDB aggregation - group by date ranges where one document can belong to several rangesMongoDB 聚合 - 按日期范围分组,其中一个文档可以属于多个范围
【发布时间】:2017-02-25 21:10:11
【问题描述】:

我有下一个虚拟数据集:

{"id": 1, "date": "2017-04-01", "total": 1}
{"id": 2, "date": "2017-04-03", "total": 2}
{"id": 3, "date": "2017-04-10", "total": 1}
{"id": 4, "date": "2017-04-11", "total": 1}

我也有一些固定值count_of_days。让它等于 5 (count_of_days = 5)

我需要创建下一组:

{"2017-04-01 + 5 days": count: 2, sum_of_total: 3}
{"2017-04-03 + 5 days": count: 1, sum_of_total: 2}
{"2017-04-10 + 5 days": count: 2, sum_of_total: 2}
{"2017-04-11 + 5 days": count: 1, sum_of_total: 1}

其中count 是日期字段在[date; date + count_of_days] 范围内的文档计数

所以对于id=1 的文档,我们有这样的组

{"2017-04-01 + 5 days": count: 2, sum_of_total: 3}

因为

doc 的 1 date[2017-04-01; 2017-04-06 (+ 5 days)] 范围内,并且

文档的 2 date 2017-04-03[2017-04-01; 2017-04-06 (+ 5 days)] 范围内

如何我可以使用aggregation frameworkMap/Reduce 来做到这一点?

主要目标是生产力和计算速度

【问题讨论】:

  • 抱歉,不清楚您要问什么,尝试重构您的问题。
  • @leonziyo 我试过了,完成了
  • 您提交的日期是字符串数据类型还是日期数据类型?
  • @leonziyo 实际上是 ISO 日期

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

我不确定如何达到您要求的确切结果,但我能够根据固定时间间隔而不是相对于记录的间隔对文档进行分组。

我假设您的文档如下所示:

{
    "_id" : ObjectId("58b36eb4b4af453e43480473"),
    "id" : 1.0,
    "date" : ISODate("2017-04-02T00:21:20.201Z"),
    "total" : 1.0
}

聚合查询:

// change this as you need, currently it is the number of milliseconds in 5 days
var interval = 1000 * 60 * 60 * 24 * 5; 

db.collection.aggregate([
    {
        $project: { 
            timestamp: { 
                $divide : [
                    { 
                        $subtract: [
                            {
                                $subtract: [ 
                                    '$date', 
                                    new Date("1970-01-01") 
                                ]
                            },
                            {
                                $mod: [
                                    {
                                        $subtract: [ 
                                            '$date', 
                                            new Date("1970-01-01") 
                                        ]
                                    },
                                    interval
                                ]
                            }
                       ] 
                    }, 
                    interval 
                ] 
            },

            date: 1,

            total: 1,

            id: 1
        }    
    },

    {
        $group: {
            _id: {
                timestamp: '$timestamp'
            },
            sum_of_total: { $sum: '$total' },
            count: { $sum: 1 }            
        }
    },

    {
        $project: {
            _id: 0,
            count: 1,
            sum_of_total: 1,
            rangeStart: { $add: [new Date(0), { $multiply: ['$_id.timestamp', interval] } ] }
        }
    },

    {
        $project: {
            _id: 0,
            count: 1,
            sum_of_total: 1,
            rangeStart: 1,
            rangeEnd: { $add: [ "$rangeStart", interval ] }
        }
    }
])

【讨论】:

    猜你喜欢
    • 2021-07-16
    • 1970-01-01
    • 2015-01-03
    • 2021-09-18
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 2014-06-04
    • 2018-01-09
    相关资源
    最近更新 更多