我有一组事件数据,我希望对这些数据执行聚合/分组,以便将事件数据汇总到单个结果中。我有一个问题,就是把我的头脑集中在如何按照我想返回结果的方式来组织数据。
样本数据:
db.events.find({})
{
    eventId : "abc",
    eventDate : 1420088400000,
    eventLength : 1800000,
    eventStart : 59100000,
    attendees : [
        "userA",
        "userB",
        "userC"
    ],
    otherData : "...",
    etc : "..."
},{
    eventId : "def",
    eventDate : 1421557200000,
    eventLength : 3600000,
    eventStart : 36000000,
    attendees : [
        "userA",
        "userG",
        "userZ"
    ],
    otherData : "...",
    etc : "..."
},{
    eventId : "ghi",
    eventDate : 1420088400000,
    eventLength : 7200000,
    eventStart : 45000000,
    attendees : [
        "userD",
        "userE",
        "userA"
    ],
    otherData : "...",
    etc : "..."
}基本上,日期/时间的/和长度都存储为表示毫秒的长或int,因此添加eventDate + eventStart将在UTC中为您提供日期和启动时间。添加eventDate + eventStart + eventLength将为您提供UTC的事件结束时间。
我想要做的是创建和聚合,允许我在与会者中的$match上进行userId (这里没有问题),但是按日/周/月/年/总体显示一组数据。
例如,示例结果(这与上面的示例数据中的时间不太准确,而是寻找如何编写分组的脚本)。
{
    userId : "userA",
    req : 75.0,
    totals : [
        {
            period : "day",
            events : 2,              //this means two event for today
            eventsLength : 7200000,  //$sum of the 2 events length
        },{
            period : "week",
            events : 3,              //this means 3 events in the week
            eventsLength : 9600000,  //$sum of the 3 events length
        },{
            period : "month",
            events : 8,              //this means 8 events in the month
            eventsLength : 15000000, //$sum of the 8 events length
        },{
            period : "year",
            events : 15,             //this means 15 events in the year
            eventsLength : 15000000, //$sum of the 15 events length
        },{
            period : "overall",
            events : 23,             //this means 23 events lifetime
            eventsLength : 72000000, //$sum of the 23 events length
        }
    ]
}因此,对于每一个“时间段”,我基本上都希望保持一个运行总量,并将$sum增加到eventLength和事件的数量。"req“是指给定当前日期,用户已经完成了3/4事件(75%)。它是独立于总数,基本上它只是一个百分比的目标是每周4个事件,这是你的百分比完成。所以你可以看到,在“一周”期间,他们只有3/4作为目标。
在我的总结中,我尝试了$match、$project和$group的组合,以尝试实现这个输出,但我希望有人能够帮助进行分组,以获得一个正在运行的总数。
我有给定当前日期的每个时间段的日期/毫秒,所以我已经将这个预先确定的变量作为变量,我只是不知道如何构造聚合/分组来产生这个结果。
任何帮助都是非常感谢的!
发布于 2015-01-21 14:41:56
在昨天对此做了一些改动之后,我有了这个解决方案,它不是我正在寻找的确切输出,在那里我将总计作为包含每个“句号”的数组或数组元素作为汇总的集合,但是这会输出一个集合,按“时间段(日/周/月/年/整体)”分割,每个集合的累计总数都是这样的。
{
    $match: {userId : "ABC123"}
},{
    $project : {
    _id : 0,
    d : {$cond:{if:{$and:[{$gte:["$eventDate", "${dayStart}"]},{$lte:["$eventDate", "${dayEnd}"]}]}, 
        then: {d : "$eventLength", c : {"$literal" : 1}}, 
        else: null }
    },
    w : {$cond:{if:{$and:[{$gte:["$eventDate","${weekStart}"]},{$lte:["$eventDate", "${weekEnd}"]}]}, 
        then: {d : "$eventLength", c : {"$literal" : 1}}, 
        else: null }
    },
    m : {$cond:{if:{$and:[{$gte:["$eventDate","${monthStart}"]},{$lte:["$eventDate","${monthEnd}"]}]}, 
        then: {d : "$eventLength", c : {"$literal" : 1}}, 
        else: null }
    },
    y : {$cond:{if:{$and:[{$gte:["$eventDate","${yearStart}"]},{$lte:["$eventDate","${yearEnd}"]}]}, 
        then: {d : "$eventLength", c : {"$literal" : 1}}, 
        else: null }
    },
    o : {$cond:{if:{$lte:["$eventDate","${yearEnd}"]}, 
        then: {d : "$eventLength", c : {"$literal" : 1}}, 
        else: null }
    }
}
},{
$group : {
    _id : null,
    day_d : {$sum : "$d.d"},
    day_c : {$sum : "$d.c"},
    week_d : {$sum : "$w.d"},
    week_c : {$sum : "$w.c"},
    month_d : {$sum : "$m.d"},
    month_c : {$sum : "$m.c"},
    year_d : {$sum : "$y.d"},
    year_c : {$sum : "$y.c"},
    over_d : {$sum : "$o.d"},
    over_c : {$sum : "$o.c"}
} 
},{
$project : {
    _id : 0,
    day : {events : "$day_c", millisTotal : "$day_d"},
    week : {events : "$week_c", millisTotal : "$week_d"},
    month : {events : "$month_c", millisTotal : "$month_d"},
    year : {events : "$year_c", millisTotal : "$year_d"},
    overall : {events : "$over_c", millisTotal : "$over_d"},
    req : {
        $cond : { 
            if : { $gte : ["$week_c", 4]}, then : 100, 
            else : {
                $cond : {
                    if : { $eq : ["$week_c", 3] }, then : 75,
                    else : {
                        $cond : {
                            if : { $eq : ["$week_c", 2] }, then : 50,
                            else : {
                                $cond : {
                                    if : { $eq : ["$week_c", 1] }, then : 25,
                                    else : 0
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
} 这将生成一个如下所示的输出。
{
day : {
    events : 1,
    millisTotal : 7200000
},
week : {
    events : 2,
    millisTotal : 14400000
},
month : {
    events : 17,
    millisTotal : 87345000
},
year : {
    events : 17,
    millisTotal : 87345000
},
overall : {
    events : 18,
    millisTotal : 92745000
},
req : 50
}我注意到的一件事是,要将$project返回到数组元素中几乎是不可能的,这样我就可以有一个“总计:[]”,每个句点集合都作为一个数组元素,但是目前这是可行的。如果有人有反馈或者有更好的方法来完成这一任务,我会把它留一段时间,看看是否有更好的答案。我之所以希望这是一个总计数组,是因为使用此输出的逻辑可能更动态,并且不会期望一组特定的“键”作为日/周/月/年/整体。
https://stackoverflow.com/questions/28049665
复制相似问题