使用mongoTemplate id增量快速遍历整张表的所有数据

我使用了junit,自己验证性的写了一下,感觉速度还是非常快的,这个。现在由于时间和场地的原因,我只提供方法的代码。对于全套的测试环境,等我这段时间忙完,我把前代码整理一下,放在我的github上,到时候欢迎小伙伴follow and star。

解决遍历整张表的思路:mongodb的id是一个自增的序列,id在创建的之初默认添加索引;有了这个性质,可以想到不断循环的读取id即可。

比如:从id为0开始,首次查询大于它的200条,下次查询:从上一次查询的结果中取出最后一条数据的id(标记为lastId);再以lastId基础继续查找下一批记录,直到下一批记录为空表示已经查询完毕。

DAO层, Lexicon根据自己mongodb的表结构来定义

    @Resource
    MongoTemplate mongoTemplate;
    public List<Lexicon> findLexiconById(String _id) {
        Query query = new Query();
        if(StringUtils.isNotBlank(_id)) {
            query.addCriteria(Criteria.where("_id").gt(new ObjectId(_id)));
        }
        query.with(new Sort(Sort.Direction.ASC, "_id")).limit(200);
        return mongoTemplate.find(query, Lexicon.class);
    }

这里的LexiconDao就是上面的DAO层

    @Autowired
    LexiconDao lexiconDao;
    String _id = null;
    int total = 0;
    //定义一个队列
    Queue<Lexicon> queue = new LinkedList<>();

    @Test
    public void testfindLexiconById() {
        Lexicon entity = null;
        int i = 1;
        //从读取数据中取出对象
        while((entity = getLexicon()) != null) {
        }

    }
    //读取数据
    public void readData() {
        List<Lexicon> list = lexiconDao.findLexiconById(_id);
        if(!CollectionUtils.isEmpty(list)) {
            queue.addAll(list);
            _id = list.get(list.size() - 1).getId();
            total = total + list.size();
        } else {
            _id = null;
        }
    }
    //从队列中获得个个对象
    public Lexicon getLexicon() {
        Lexicon entity = queue.poll();
        if(entity == null) {
            readData();
            entity = queue.poll();
        }
        return entity;
    }

 

上面的代码不够友好,下面是改进的代码,思路还是原来的根据id自增序列的性质进行查找。自增查找到的dao代码如下,通过泛型方法可以适用任何的类进行id自增序列查找。

//mongodb查询所有的数据
public <T> List<T> findByCursorId(String id, 
Class<T> t, final String collectionName) {

	Query query = new Query();
	if (StringUtils.isNotBlank(id)) {
		query.addCriteria(Criteria.where("_id").gt(new ObjectId(id)));
	}
	if (StringUtils.isBlank(id)) {
		query.addCriteria(Criteria.where("_id").gt(new ObjectId(new Date(0))));
	}
	query.limit(20);
	return mongoTemplate.find(query, t, collectionName);
}

查找全部数据的处理方法

List<UserItemList> userItemListList = dao.findByCursorId(null, UserItemList.class, userItemListCollection);
int sum = 0;
while (!CollectionUtils.isEmpty(userItemListList)) {
	sum += userItemListList.size();
	//处理数据模块
	handle(userItemListList);
	
	//上一次查询记录最后一条id
	String lastId = userItemListList.get(userItemListList.size() - 1).get_id();
	userItemListList = dao.findByCursorId(lastId, UserItemList.class, userItemListCollection);
}

 

代码在生产环境下验证过,自己的水平原因可能存在错误和想给意见的,email: chenrui@marsdl.com

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值