1.准备环境

  1.1 mongodb下载

  1.2 mongodb启动

    C:\mongodb\bin\mongod --dbpath D:\mongodb\data

  1.3 可视化mongo工具Robo 3T下载

2.准备数据

  

        <dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.6.1</version>
</dependency>

java代码执行

    public static void main(String[] args) {

        try {

            /**** Connect to MongoDB ****/
// Since 2.10.0, uses MongoClient
MongoClient mongo = new MongoClient("localhost", 27017); /**** Get database ****/
// if database doesn't exists, MongoDB will create it for you
DB db = mongo.getDB("www"); /**** Get collection / table from 'testdb' ****/
// if collection doesn't exists, MongoDB will create it for you
DBCollection table = db.getCollection("person"); /**** Insert ****/
// create a document to store key and value
BasicDBObject document=null; for(int i=0;i<100000000;i++) {
document = new BasicDBObject();
document.put("name", "mkyong"+i);
document.put("age", 30);
document.put("sex", "f");
table.insert(document);
} /**** Done ****/
System.out.println("Done"); } catch (UnknownHostException e) {
e.printStackTrace();
} catch (MongoException e) {
e.printStackTrace();
} }

3.分页查询

 传统的limit方式当数据量较大时查询缓慢,不太适用。考虑别的方式,参考了logstash-input-mongodb的思路:

  public
def get_cursor_for_collection(mongodb, mongo_collection_name, last_id_object, batch_size)
collection = mongodb.collection(mongo_collection_name)
# Need to make this sort by date in object id then get the first of the series
# db.events_20150320.find().limit(1).sort({ts:1})
return collection.find({:_id => {:$gt => last_id_object}}).limit(batch_size)
end collection_name = collection[:name]
@logger.debug("collection_data is: #{@collection_data}")
last_id = @collection_data[index][:last_id]
#@logger.debug("last_id is #{last_id}", :index => index, :collection => collection_name)
# get batch of events starting at the last_place if it is set last_id_object = last_id
if since_type == 'id'
last_id_object = BSON::ObjectId(last_id)
elsif since_type == 'time'
if last_id != ''
last_id_object = Time.at(last_id)
end
end
cursor = get_cursor_for_collection(@mongodb, collection_name, last_id_object, batch_size)

使用java实现

import java.net.UnknownHostException;
import java.util.List; import org.bson.types.ObjectId; import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoException; public class Test { public static void main(String[] args) {
int pageSize=50000; try { /**** Connect to MongoDB ****/
// Since 2.10.0, uses MongoClient
MongoClient mongo = new MongoClient("localhost", 27017); /**** Get database ****/
// if database doesn't exists, MongoDB will create it for you
DB db = mongo.getDB("www"); /**** Get collection / table from 'testdb' ****/
// if collection doesn't exists, MongoDB will create it for you
DBCollection table = db.getCollection("person");
DBCursor dbObjects;
Long cnt=table.count();
//System.out.println(table.getStats());
Long page=getPageSize(cnt,pageSize);
ObjectId lastIdObject=new ObjectId("5bda8f66ef2ed979bab041aa"); for(Long i=0L;i<page;i++) {
Long start=System.currentTimeMillis();
dbObjects=getCursorForCollection(table, lastIdObject, pageSize);
System.out.println("第"+(i+1)+"次查询,耗时:"+(System.currentTimeMillis()-start)/1000+"秒");
List<DBObject> objs=dbObjects.toArray();
lastIdObject=(ObjectId) objs.get(objs.size()-1).get("_id"); } } catch (UnknownHostException e) {
e.printStackTrace();
} catch (MongoException e) {
e.printStackTrace();
} } public static DBCursor getCursorForCollection(DBCollection collection,ObjectId lastIdObject,int pageSize) {
DBCursor dbObjects=null;
if(lastIdObject==null) {
lastIdObject=(ObjectId) collection.findOne().get("_id"); //TODO 排序sort取第一个,否则可能丢失数据
}
BasicDBObject query=new BasicDBObject();
query.append("_id",new BasicDBObject("$gt",lastIdObject));
BasicDBObject sort=new BasicDBObject();
sort.append("_id",1);
dbObjects=collection.find(query).limit(pageSize).sort(sort);
return dbObjects;
} public static Long getPageSize(Long cnt,int pageSize) {
return cnt%pageSize==0?cnt/pageSize:cnt/pageSize+1;
} }

4.一些经验教训

  1. 不小心漏打了一个$符号,导致查询不到数据,浪费了一些时间去查找原因

query.append("_id",new BasicDBObject("$gt",lastIdObject));
2.创建索引
  创建普通的单列索引:db.collection.ensureIndex({field:1/-1});  1是升续 -1是降续
实例:db.articles.ensureIndex({title:1}) //注意 field 不要加""双引号,否则创建不成功
  查看当前索引状态: db.collection.getIndexes();
  实例:
  db.articles.getIndexes();
  删除单个索引db.collection.dropIndex({filed:1/-1});

3.执行计划

  db.student.find({"name":"dd1"}).explain()

参考文献:

【1】https://github.com/phutchins/logstash-input-mongodb/blob/master/lib/logstash/inputs/mongodb.rb

【2】https://www.cnblogs.com/yxlblogs/p/4930308.html

【3】https://docs.mongodb.com/manual/reference/method/db.collection.ensureIndex/

亿级别记录的mongodb分页查询java代码实现的更多相关文章

  1. 亿级别记录的mongodb批量导入Es的java代码完整实现

    针对mongodb亿级别或者十亿级别的模糊查询,效率不高,解决方式是使用Es查询,这样就需要把数据导入的ES中 完整的代码实现如下所示:(仅供参考) import java.io.IOExceptio ...

  2. MongoDB分页的Java实现和分页需求的思考

    前言 传统关系数据库中都提供了基于row number的分页功能,切换MongoDB后,想要实现分页,则需要修改一下思路. 传统分页思路 假设一页大小为10条.则 //page 1 1-10 //pa ...

  3. Mybatis包分页查询java公共类

    Mybatis包分页查询java公共类   分页----对于数据量非常大的查询中.是不可缺少的. mybatis底层的分页sql语句因为须要我们自己去手动写.而实现分页显示的时候我们须要依据分页查询条 ...

  4. 分页查询关键代码 多条件查询关键代码 删除选中商品关键代码 修改要先回显再修改 修改要先回显再修改 同一业务集中使用同一servlet的方法

    分页查询关键代码: 通过servlet转发回来的各种信息进行分页的设计(转发回的信息有 分页查询的List集合 查询的页码 查询的条数 查询的数据库总条数 查询的总页码) 从开始时循环10次出现十个数 ...

  5. MongoDB 分页查询的方法及性能

    最近有点忙,本来有好多东西可以总结,Redis系列其实还应该有四.五.六...不过<Redis in Action>还没读完,等读完再来总结,不然太水,对不起读者. 自从上次Redis之后 ...

  6. C#MongoDB 分页查询的方法及性能

    传统的SQL分页 传统的sql分页,所有的方案几乎是绕不开row_number的,对于需要各种排序,复杂查询的场景,row_number就是杀手锏.另外,针对现在的web很流行的poll/push加载 ...

  7. Spring Data MongoDB 分页查询

    在上篇文章 Spring Data MongoDB 环境搭建 基础上进行分页查询 定义公用分页参数类,实现 Pageable 接口 import java.io.Serializable; impor ...

  8. (记录)mysql分页查询,参数化过程的坑

    在最近的工作中,由于历史遗留,一个分页查询没有参数化,被查出来有sql注入危险,所以对这个查询进行了参数化修改. 一看不知道,看了吓一跳,可能由于种种原因,分页查询sql是在存储过程中拼接出来的,wh ...

  9. 使用mybatis实现分页查询示例代码分析

    *******************************************分页查询开始*************************************************** ...

随机推荐

  1. Spring中ApplicationContext和beanfactory区别---解析一

    BeanFacotry是spring中比较原始的Factory.如XMLBeanFactory就是一种典型的BeanFactory.原始的BeanFactory无法支持spring的许多插件,如AOP ...

  2. SQL Union 和Union All 的区别

    Union与Union All的区别 如果我们需要将两个select语句的结果作为一个整体显示出来,我们就需要用到union或者union all关键字.union(或称为联合)的作用是将多个结果合并 ...

  3. Programmatically Disable Event Firing on List Item Update in SharePoint 2010

    1. Microsoft.SharePoint.dll Create EventFiring.cs 1.Right-click on the project, select Add and click ...

  4. iOS View 外层奇怪的黑线

    最近碰到一个问题,当时是为了建了一个能自动适应内容的 Label.根据内容,我计算出需要的尺寸,然后把新尺寸设置给 Label. 但是显示的时候,一个奇怪的现象出现了,Label 的顶端总是有一条浅浅 ...

  5. https经过ngxin在web服务器收到http请求

    一. 问题描述: nginx代理nexus的时候页面不全,部分https地址自动转成http了,使用方案四解决的 浏览器输入https://www.mysite.com,后台通过request.get ...

  6. python--生成器,生成器推导式, yield from

    一.生成器 生成器的本质就是迭代器,它一个一个的创建对象. 在python中有三种方式获取生成器: 1.通过生成器函数 2.通过各种推导式来实现生成器 3.通过数据的类型转换也可以获取生成器 二.生成 ...

  7. 【OCP-052】052最新考试题库分析整理-第7题

    7.Which is true about external tables? A) The ORACLE_DATAPUMP access driver can be used to write dat ...

  8. 3D-2D:PnP

    PnP(Perspective-n-Point):当知道n个3D空间点及其投影位置时,估计相机位姿. 2D-2D的对极几何方法需要八个或八个以上的点对(以八点法为例),且存在着初始化.纯旋转和尺度的问 ...

  9. angular核心原理解析1:angular自启动过程

    angularJS的源代码整体上来说是一个自执行函数,在angularJS加载完成后,就会自动执行了. angular源代码中: angular = window.angular || (window ...

  10. jquery源码解析:jQuery数据缓存机制详解1

    jQuery中有三种添加数据的方法,$().attr(),$().prop(),$().data().但是前面两种是用来在元素上添加属性值的,只适合少量的数据,比如:title,class,name等 ...