每次用户登录或注销时,事件都会保存在mongo中。用户一天可以多次登录和/或注销。
例如,鲍勃(Bob)拥有2次登录和1次注销:
{
username: ‘bob’,
type: ‘login’,
eventDate: ISODate(‘2018-09-21T12:39:50.676Z’)
}
{
username: ‘bob’,
type: ‘login’,
eventDate: ISODate(‘2018-09-21T13:55:50.676Z’)
}
{
username: ‘bob’,
type: ‘logout,
eventDate: ISODate(‘2018-09-21T22:10:50.676Z’)
}
James只有1个登录事件:
{
username: ‘james’,
type: ‘login,
eventDate: ISODate(‘2018-09-21T10:10:50.676Z’)
}
我想执行一个查询,该查询将为每个用户每天检索当天的首次登录和最后的注销(例如,在过去一周)。
结果将是:
[{
username: ‘bob’,
firstLogin: ISODate(‘2018-09-21T12:39:50.676Z’),
lastLogout: ISODate(‘2018-09-21T22:10:50.676Z’)
}
{
username: ‘james’,
firstLogin: ISODate(‘2018-09-22T10:19:50.676Z’),
lastLogout: null,
}]
我认为我必须处理“聚合”问题,但不确定。
答案 0 :(得分:2)
通过使用两个级别的$group
:(MongoDB V3.2.18)
我相信用户名是唯一的。
$sort
eventDate 。$group
通过用户名和类型。$project
来区分 firstLogin 和 lastLogin 。$group
,以获得最终结果。db.getCollection('test').aggregate([
{$sort: {'eventDate' : 1}},
{
"$group" : {
_id: {"username" : "$username", "type": "$type"},
eventDate: {$push: "$eventDate"}
}
},
{
$project : {
_id:1,
eventDate:1,
firstLogin: {
$cond: [ { "$eq": ["$_id.type", "login" ]}, { $arrayElemAt: [ "$eventDate", 0 ] }, null]
},
lastLogout: {
$cond: [ { "$eq": ["$_id.type", "logout" ]}, { $arrayElemAt: [ "$eventDate", -1 ] }, null]
}
}
},
{
"$group" : {
_id: "$_id.username",
firstLogin: {$first: "$firstLogin"},
lastLogout: {$last: "$lastLogout"}
}
}
]);
输出:
/* 1 */
{
"_id" : "james",
"firstLogin" : ISODate("2018-09-21T10:10:50.676Z"),
"lastLogout" : null
}
/* 2 */
{
"_id" : "bob",
"firstLogin" : ISODate("2018-09-21T12:39:50.676Z"),
"lastLogout" : ISODate("2018-09-21T22:10:50.676Z")
}
答案 1 :(得分:1)
您可以通过单个group
来实现。
同一用户的不同日子也可以工作。
在
type
前返回最后一个日期和第一个日期。在MongoDB GUI上进行了测试。
db.getCollection("loginDetail").aggregate([
{
$group: {
_id: {
username: "$username",
year: { $year: "$eventDate" },
month: { $month: "$eventDate" },
day: { $dayOfMonth: "$eventDate" }
},
firstLogin: {
$min: {
$cond: [{ $and: [{ $eq: ["$type", "login"] }] }, "$eventDate", null]
}
},
lastLogout: {
$max: {
$cond: [{ $and: [{ $eq: ["$type", "logout"] }] }, "$eventDate", null]
}
}
}
},
{
$project: {
_id: 1,
username : '$_id.username',
firstLogin :1,
lastLogout :1
}
}
]);