根据 mongodb 个事件计算 DAU/MAU
Calculate DAU/MAU from mongodb events
目前情况如下:
collection.aggregate(
[
{
$match: {
ct: {$gte: dateFrom, $lt: dateTo },
}
},
{
$group: {
_id: '$user'
}
}
]
).toArray((err, result) => {
callback(err, result.length)
});
这让我得到了一个这样的用户列表,我可以算作 DAU/MAU:
但我认为这样做效率不高,正确的做法是什么?
我对一个大型事件数据库进行了快速测试,如果您有正确的索引,使用不同的计数比聚合要快得多:
collection.distinct('user', { ct: { $gte: dateFrom, $lt: dateTo } }).length
您可以针对每天和每月的唯一活跃用户使用以下聚合。我假设 ct 作为时间戳字段。
db.collection.aggregate(
[
{"$match":{"ct":{"$gte":dateFrom,"$lt":dateTo}}},
{"$facet":{
"dau":[
{"$group":{
"_id":{
"user":"$user",
"ymd":{"$dateToString":{"format":"%Y-%m-%d","date":"$ct"}}
}
}},
{"$group":{"_id":"$_id.ymd","dau":{"$sum":1}}}
],
"mau":[
{"$group":{
"_id":{
"user":"$user",
"ym":{"$dateToString":{"format":"%Y-%m","date":"$ct"}}
}
}},
{"$group":{"_id":"$_id.ym","mau":{"$sum":1}}}
]
}}
])
DAU
db.collection.aggregate(
[
{"$match":{"ct":{"$gte":dateFrom,"$lt":dateTo}}},
{"$group":{
"_id":{
"user":"$user",
"ymd":{"$dateToString":{"format":"%Y-%m-%d","date":"$ct"}}
}
}},
{"$group":{"_id":"$_id.ymd","dau":{"$sum":1}}}
])
月活跃用户
db.collection.aggregate(
[
{"$match":{"ct":{"$gte":dateFrom,"$lt":dateTo}}},
{"$group":{
"_id":{
"user":"$user",
"ym":{"$dateToString":{"format":"%Y-%m","date":"$ct"}}
}
}},
{"$group":{"_id":"$_id.ym","mau":{"$sum":1}}}
])
可以在分组时使用sum
collection.aggregate([
{ $match: {'date': {$gte: dateFrom, $lt: dateTo }}}, // fetch all requests from/to
{ $group: { _id: '$user', total: { $sum: 1 }}}, // group all requests by user and sum the count of collection for a group
{ $sort: { total: -1 }}
], function (err, result) {
if (err) cb(err, null);
cb(null, result);
});
目前情况如下:
collection.aggregate(
[
{
$match: {
ct: {$gte: dateFrom, $lt: dateTo },
}
},
{
$group: {
_id: '$user'
}
}
]
).toArray((err, result) => {
callback(err, result.length)
});
这让我得到了一个这样的用户列表,我可以算作 DAU/MAU:
但我认为这样做效率不高,正确的做法是什么?
我对一个大型事件数据库进行了快速测试,如果您有正确的索引,使用不同的计数比聚合要快得多:
collection.distinct('user', { ct: { $gte: dateFrom, $lt: dateTo } }).length
您可以针对每天和每月的唯一活跃用户使用以下聚合。我假设 ct 作为时间戳字段。
db.collection.aggregate(
[
{"$match":{"ct":{"$gte":dateFrom,"$lt":dateTo}}},
{"$facet":{
"dau":[
{"$group":{
"_id":{
"user":"$user",
"ymd":{"$dateToString":{"format":"%Y-%m-%d","date":"$ct"}}
}
}},
{"$group":{"_id":"$_id.ymd","dau":{"$sum":1}}}
],
"mau":[
{"$group":{
"_id":{
"user":"$user",
"ym":{"$dateToString":{"format":"%Y-%m","date":"$ct"}}
}
}},
{"$group":{"_id":"$_id.ym","mau":{"$sum":1}}}
]
}}
])
DAU
db.collection.aggregate(
[
{"$match":{"ct":{"$gte":dateFrom,"$lt":dateTo}}},
{"$group":{
"_id":{
"user":"$user",
"ymd":{"$dateToString":{"format":"%Y-%m-%d","date":"$ct"}}
}
}},
{"$group":{"_id":"$_id.ymd","dau":{"$sum":1}}}
])
月活跃用户
db.collection.aggregate(
[
{"$match":{"ct":{"$gte":dateFrom,"$lt":dateTo}}},
{"$group":{
"_id":{
"user":"$user",
"ym":{"$dateToString":{"format":"%Y-%m","date":"$ct"}}
}
}},
{"$group":{"_id":"$_id.ym","mau":{"$sum":1}}}
])
可以在分组时使用sum
collection.aggregate([
{ $match: {'date': {$gte: dateFrom, $lt: dateTo }}}, // fetch all requests from/to
{ $group: { _id: '$user', total: { $sum: 1 }}}, // group all requests by user and sum the count of collection for a group
{ $sort: { total: -1 }}
], function (err, result) {
if (err) cb(err, null);
cb(null, result);
});