MongoDB多层次小组

字节压缩

我有一组事件数据,我想对它们进行汇总/分组以将事件数据汇总为一个结果。我遇到的一个问题就是让我全神贯注于如何以我想返回结果的方式组织数据。

样本数据:

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 : "..."
}

基本上,日期/时间/和长度都存储为代表毫秒的long或int,因此添加eventDate + eventStart会为您提供UTC的日期和开始时间。添加eventDate + eventStart + eventLength将为您提供UTC中的事件结束时间。

我想做的是创建并聚合,使我可以对与会人员中的userId进行$ match(此处无问题),但按日/周/月/年/总体显示数据分组。

因此,以示例结果为例(这与上面的示例数据中的时间并不准确,而是在寻找如何编写此分组的脚本。)

{
    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和事件数。“要求”表示给定当前日期,用户已完成3/4个事件(75%)。它与总数无关,基本上说目标是每周4次活动,这只是一个百分比,这是您的完成百分比。因此,您看到在“周”期间,他们只有4个目标中的3个。

在我的总计中,我尝试将$ match,$ project和$ group组合使用,以尝试生成此输出,但是我希望有人可以为分组提供帮助,以实现总计。

我有给定当前日期的每个周期的日期/毫秒,因此我已经预先确定了该日期/毫秒作为变量,我只是不知道如何构造聚合/分组以产生此结果。

任何帮助表示赞赏!

字节压缩

在昨天弄乱了一点之后,我有了这个解决方案,它不是我想要的确切输出,因为我将每个“时期”或数组元素作为一个总计的集合作为一个数组总计,但是输出一个集合,该集合按“期间(天/周/月/月/年/总体)细分”,每个集合的累加总数。

{
    $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放回到数组元素中,这样我就可以将每个period集合作为数组元素使用“ totals:[]”,但是现在可以使用。一个更好的方法来完成此操作,我将对此开放一会儿,看看是否有更好的答案。.我之所以将其作为总计数组,是因为使用此输出的逻辑可以更加动态,并且不希望将特定的一组“键”设置为日/周/月/年/总体。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章