MongoTemplate执行aggregate操作时集合不存在不报错的原因及实现方案
为什么MongoTemplate查询不存在的集合不会抛错
- MongoDB 原生对不存在的集合执行读操作(包括聚合、普通查询)时,默认将其作为空集合处理,本身不会抛出服务端错误。
- Spring Data MongoDB 的 MongoTemplate 设计完全对齐MongoDB原生行为,因此聚合不存在的集合时,只会拿到空结果集,
getMappedResults()默认返回空列表,若你的聚合逻辑包含取首条结果之类的封装,就会得到null值,全程不会触发异常。
无需单独校验的实现方案
你可以直接在原有聚合管道的最开头添加一个$collStats聚合阶段,这个阶段只有集合存在时才能执行成功,不存在会直接抛出服务端错误,不需要额外写单独的集合存在校验逻辑,也没有额外的接口调用开销。
代码示例
低版本Spring Data MongoDB通用写法
// 构造聚合时在最开头插入校验阶段 Aggregation aggregation = Aggregation.newAggregation( // 新增集合存在性校验阶段 new AggregationOperation() { @Override public Document toDocument(AggregationOperationContext context) { return new Document("$collStats", new Document("count", new Document())); } }, // 此处放你原来的所有聚合阶段,不需要改动 Aggregation.match(Criteria.where("yourField").is("yourValue")), // 其他原有阶段... ); // 原有调用逻辑不需要改动 List<Response> results = mongoTemplate.aggregate(aggregation, Request.class, Response.class).getMappedResults();
3.0+版本简洁写法
如果使用Spring Data MongoDB 3.0及以上版本,可以直接用内置API:
Aggregation aggregation = Aggregation.newAggregation( Aggregation.collStats(), // 原有聚合阶段... );
效果说明
- 目标集合不存在时,MongoDB服务端会直接返回错误,MongoTemplate会将其转换为
DataAccessException的对应子类抛出,你可以按需捕获处理即可。 - 目标集合存在时,
$collStats阶段不会影响后续聚合逻辑,原有业务查询结果完全不变,也不会有额外的性能损耗。
内容的提问来源于stack exchange,提问作者prabhakar srivastava
相关产品推荐
相关产品推荐

