1 场景
java中,mongo中查询海量数据
时,如果将数据全部查询出来进行处理,会占用大量的堆内存
,容易导致内存溢出
,程序崩溃。
面对此问题,通常采用的问题是分页查询
:先查询总数
,再根据总数进行分页查询
。
mongo 在分页查询时,如果数据量特别大,查询到后面的页
,会越来越慢
。此种情况,可以根据实际情况,对数据进行排序查询后,查询条件加上大于
上页最后一条
数据的排序键
来提升速度(这种查询方式,当数据量比加大时,也可在前台页面分页查询
时使用)。
这里,我们使用mongo查询中更友好的查询方式:游标
,来实现在mongo中对海量数据的查询。
2 版本
springBoot:2.2.9.RELEASE
mongo:4.0
3 步骤
//组装查询条件
Query query=new Query();
query.with(Sort.by(new Sort.Order(Sort.Direction.ASC, "_id")));
try (MongoCursor<Document> cursor =
//指定查询集合
mongoTemplate.getCollection("xxx[表名]")
//组装查询条件
.find(query.getQueryObject())
//组装排序方式(非必须,可不设置)
.sort(query.getSortObject())
//设置游标查询不超时
.noCursorTimeout(true)
//设置批量从数据库中获取的数据量
.batchSize(1000)
.cursor()) {
Document doc;
//Map map;
while (cursor.hasNext()) {
//写法1(建议)
doc = cursor.next();
System.out.println(doc.get("xxx[属性名]"));
//写法2(不建议)
//map=cursor.next();
//System.out.println(map.get("xxx[属性名]"));
}
} catch (Exception e) {
e.printStackTrace();
}
4 说明
- 设置游标查询不超时
noCursorTimeout(true)
必须设置此属性,防止数据库连接超时,导致的游标连接自动关闭
。
- 设置批量从数据库中获取的数据量
batchSize(1000)
建议根据实际业务情况
而设置,设置此批次属性,游标的迭代器进行查询时,会根据需要
,去数据库获取指定批量
的数据,缓存
起来供迭代器使用,而不是每次next()获取数据的时候
,均去查询数据库,减少数据库查询次数
,提高了效率。