0x01 数据存储结构
前段时间发现公司原来的一个业务,使用mysql分月创建表记录用户登陆记录信息,在表数量达到千万级后,查询变得超级慢,并且时不时的卡死终端,为了解决这个问题,没有选择花大力气去优化,而是选择了使用MongoDB数据库去存储,记过几个月的数据存储,数据量早已达到五千万级别,但查询速度依然很快。
MongoDB存储了大量的用户登录记录,文档结构如下:
{
"_id" : ObjectId("5a1fde257756dca1c86f2d23"),
"_class" : "com.aaa.LoginHistory",
"uid" : "94989242",
"ip" : "192.168.1.219",
"imei" : "865736037366641",
"epid" : "33189023-9472-4f30-81cf-8c7d13132aae5",
"platform" : "Android",
"timestamp" : "1512037117100",
"address" : "中国,江苏省,南京市,建邺区"
}
0x02 初试Aggregate
现在有个需求,需要统计每一天(yyyy-MM-dd)的登录用户数(uid对应用户,每天存在多次登陆记录,即uid可能重复)。
由于技术菜,选择了比较low的方法实现:根据需要查询的时间间隔的时间,就是开始时间戳和结束时间戳,把它分成每天一个间隔,然后利用以下方法去统计:
db.loginHistory.aggregate([
{
$match:{
"timestamp":{
"$lte":"1513412162000","$gte":"1512548162000"}
}
},
{
$group:{
_id:{
"uid":"$uid"},
"count":{
"$avg":1}
}
},
{
$group:{
_id:"统计",
"count":{
"$sum":1}
}
}
])
可以得到某个时间间隔内的uid数量:
{ "_id" : "统计", "count" : 30003 }
对应的java代码实现
开始时间
long startTime = startCalendar.getTimeInMillis();
结束时间
long endTime = endCalendar.get