Spring MongoTemplate执行聚合命令如何分批获取全部结果?
分批获取MongoDB聚合查询全部结果的方案
判断是否存在更多结果
执行初始聚合命令后,从返回的cursor文档中读取id字段:
- 如果
cursor.id不为0,说明还有未获取的结果批次; - 当所有结果都获取完成后,
cursor.id会变为0。
分批获取全部结果的实现代码
通过getMore命令循环获取后续批次,直到游标id变为0:
// 初始聚合命令 String jsonCommand = "{ aggregate: 'CollectionName', pipeline: [ { $match: { ... } } ], cursor: { } }"; Document commandResult = mongoTemplate.executeCommand(jsonCommand); Document cursorDoc = commandResult.get("cursor", Document.class); // 初始化结果列表,加入第一批次数据 List<Document> allDocuments = new ArrayList<>(cursorDoc.getList("firstBatch", Document.class)); long cursorId = cursorDoc.getLong("id"); // 循环拉取后续批次 while (cursorId != 0) { // 构造getMore命令 Document getMoreCommand = new Document("getMore", cursorId) .append("collection", "CollectionName"); Document getMoreResult = mongoTemplate.executeCommand(getMoreCommand); Document nextCursorDoc = getMoreResult.get("cursor", Document.class); List<Document> nextBatch = nextCursorDoc.getList("nextBatch", Document.class); allDocuments.addAll(nextBatch); // 更新游标id,判断是否继续循环 cursorId = nextCursorDoc.getLong("id"); }
注意事项
- 游标有默认超时时间(10分钟),如果处理大批次数据耗时较长,可以在初始聚合命令的
cursor中添加noTimeout: true来避免游标被提前关闭:cursor: { noTimeout: true } - 每次
getMore命令会沿用初始聚合查询的游标上下文,无需重复传入pipeline参数 - 若设置了
noTimeout,建议所有数据处理完成后,手动调用killCursors命令关闭游标,避免资源浪费
内容的提问来源于stack exchange,提问作者Daniel X
相关产品推荐
相关产品推荐

