MongoDB聚合-按日期范围分组,其中一个文档可以属于多个范围

MongoDB聚合-按日期范围分组,其中一个文档可以属于多个范围,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有下一个虚拟数据集: {"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\u of \u days。让它等于5(count\u of\u days=5) 我需要创

我有下一个虚拟数据集:

{"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\u of \u days
。让它等于5(
count\u of\u 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
是日期字段在范围内的文档计数
[日期;日期+天数]

因此,对于id=1的文档,我们有这样的组

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

文件1的日期在范围内(2017-04-01;2017-04-06(+5天)和

文件的2号日期在范围内
2017-04-03
[2017-04-01;2017-04-06(+5天)]

如何使用
aggregation framework
Map/Reduce


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

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

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

{
    "_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 ] }
        }
    }
])

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

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

{
    "_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 ] }
        }
    }
])

抱歉,但不清楚您想问什么,请尝试重构您的问题。@leonziyo我已经尝试过,您的日期是字符串数据类型还是日期数据类型?@leonziyo实际上是ISO date抱歉,但不清楚您想问什么,请尝试重构您的问题。@leonziyo我已经尝试过,您的日期是字符串数据类型还是日期数据类型?@leonziyo实际上是ISO日期