开发者社区> 谢一鸣> 正文

如何遍历数据量亿级别Mongo库

简介:
+关注继续查看

场景介绍

在使用Mongo这种非关系型数据库过程中,往往存储了海量的数据,这些数据的数据结构非常松散,数据类型比较复杂。对于从海量数据中提取或分析数据,需要遍历Mongo库的情况经常出现,这里介绍两种比较有效的方法,均在亿级别的生产库中,多次使用过。

方法一:利用时间戳

在存储的数据中,对时间戳字段,建立索引,如下方数据时间戳字段为update_time

 {
    "_id" : "6214627359000222889",
    "_class" : "com.alibaba.fastjson.JSONObject",
    "update_time" : ISODate("2018-07-05T14:26:42.018Z"),
    "idcard" : "342522199406220025",
    "gender" : "女",
    "age" : "24",
    "name" : "曹××"
}

这种方法遍历,我们需要一个起点时间,和结束时间,然后按照这个时间段进行扫库,亿级别的数据,不可能全部取出,可每次取出一定数量,比如1K条,排序后根据最后一条的时间戳,与结束时间根据你是逆序遍历,还是顺序遍历进行判断,如此循环,Demo如下。

   //顺序遍历,所以结束时间为当前时间
   Date endDate = new Date();
  //开始时间
   Date startDate = minDate;
   while(startDate < endDate ){
       Query query = new Query();
       query.addCriteria(Criteria.where("update_time").gt(startDate));
       //这里可以自己写一些查询条件

       //对时间的排序
       query.with(new Sort(new Sort.Order(Sort.Direction.ASC,"update_time")));
       query.limit(1000);
       List<JSONObject> list =  mongoTemplate.find(query,JSONObject.class,"collectionName");
       //将每次取出的最后时间,赋值,然后跟结束时间比较
       startDate = list.get(list.size()-1).getDate("update_time");
       //处理数据
       for(JSONObject json:list){
            
        }
    }
   

要点

  • 必须拥有时间戳字段,且必须建立索引;
  • 需要查出最大时间和最小时间;

这两个点,也是这种方法的缺点,有些库中时间戳字段没有建立索引,或者库中的有些数据也没有时间戳,或者时间戳错误,这些情况就没法使用这种方法扫库遍历。可以使用第二种方法。

方法二:Mongo 游标的使用(推荐)

Mongo的游标无论是功能还是使用的便捷上,都比MySQL强上许多,在MySQL中使用游标还需要PL/SQL编程,比较麻烦而Mongo却不用。Mongo中的游标可以实现根据条件查询和指定使用投影运算符返回匹配文档中的所有字段。并返回到匹配文档的游标,可以随意修改查询限制、跳跃、和排序顺序的功能。Demo如下

BasicDBObject query = new BasicDBObject();
//查询条件,比如年龄,性别之内的,比如筛选,性别男性,年龄30岁以下,20岁以上。
query.put("gender", "男");
query.put("age",new BasicDBObject().append("$gte",20).append("$lt",30));
DBCursor cursor = mongoTemplate.getCollection("collectionName").find(query);
//防止超时
cursor.addOption(Bytes.QUERYOPTION_NOTIMEOUT);
while (cursor.hasNext()) {
   //数据取出
   DBObject reuslt =  cursor.next();
}

使用cursor来进行遍历,cursor会每次取出一定的数据量,也已经对库中的数据进行了排序,在进行数据处理同时cursor一直都在进行遍历的操作,极大的增快了效率。

优点

相较于第一种根据时间戳来进行遍历的方法,使用游标的会比较方便,不用建立索引,不用考虑分页的操作。

备注

无论是哪种方法,在遍历跑批过程中最好记录一下当前遍历的位置,一旦程序出现异常中断,避免从头跑批。比如,使用时间戳来遍历,记录一下当前遍历到了数据的时间,程序异常中断时根据记录的时间来重新遍历,使用游标的时候,定义一个计数器,异常中断时,重启后,可以用skip从中断点开始。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
14236 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
28389 0
Mongo:update更新多条数据
Mongo:update更新多条数据
44 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
20318 0
Serverless 解惑——函数计算如何访问 Mongo 数据库
函数计算(Function Compute):函数计算 是事件驱动的全托管计算服务。使用函数计算,您无需采购与管理服务器等基础设施,只需编写并上传代码。函数计算为您准备好计算资源,弹性地可靠地运行任务,并提供日志查询、性能监控和报警等功能。
1155 0
Serverless 解惑——函数计算如何访问 Mongo 数据库
本文介绍如何快速实现函数计算访问 Mongo 数据库。
1282 0
+关注
谢一鸣
软件工程专业毕业,最喜欢的书籍是软件工程领域的《人月神话》,Java程序猿一枚,熟悉敏捷开发以及java并发编程。
5
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载