MongoDB上MapReduce的实现以及项目实例探索

本文介绍了如何使用MongoDB的MapReduce功能解决海量用户登录记录的统计问题。从数据存储结构到使用Aggregate初步尝试,再到最终采用MapReduce实现高效统计,详细阐述了整个过程。在MapReduce中,通过map函数处理时间戳并去重,reduce函数进行用户登录计数,从而避免了使用Aggregate可能导致的时间开销大的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值