Spring Data MongoDB聚合查询返回空结果,请求排查解决
问题:Spring MongoDB聚合统计字段值出现次数返回空Map
使用Spring Framework的MongoTemplate统计集合中指定字段各值的出现次数,编写了countFieldValuesOccurrences方法,但返回空Map,期望得到类似{"Available":1,"Out of stock":3}的结果。
现有代码
ComicService类
public class ComicService { @Autowired private MongoTemplate mongoTemplate; public Map<Object, Long> countFieldValuesOccurrences(String collectionName, String fieldName) { GroupOperation groupOperation = Aggregation.group(fieldName).count().as("count"); Aggregation aggregation = Aggregation.newAggregation(groupOperation); AggregationResults<FieldValueCount> result = mongoTemplate.aggregate(aggregation, collectionName, FieldValueCount.class); List<FieldValueCount> fieldValueCounts = result.getMappedResults(); Map<Object, Long> fieldValueOccurrences = new HashMap<>(); for (FieldValueCount fieldValueCount : fieldValueCounts) { fieldValueOccurrences.put(fieldValueCount.getFieldValue(), fieldValueCount.getCount()); } System.out.println(fieldValueCounts); return fieldValueOccurrences; } }
FieldValueCount类
public class FieldValueCount { private Object fieldValue; private long count; public Object getFieldValue() { return fieldValue; } public long getCount() { return count; } }
实际输出:
{}
排查与修复步骤
1. 核心问题:聚合结果映射错误
MongoDB的$group聚合操作默认将分组字段的值存入_id字段,而非你传入的fieldName。你的FieldValueCount类未将fieldValue映射到_id,且缺少setter方法,导致Spring Data MongoDB无法正确映射结果,最终得到空列表。
修复方案:
修改FieldValueCount类,添加字段映射注解和setter方法:
import org.springframework.data.mongodb.core.mapping.Field; public class FieldValueCount { @Field("_id") private Object fieldValue; private long count; public Object getFieldValue() { return fieldValue; } public void setFieldValue(Object fieldValue) { this.fieldValue = fieldValue; } public long getCount() { return count; } public void setCount(long count) { this.count = count; } }
2. 验证聚合逻辑正确性
先在MongoDB客户端直接执行聚合命令,确认是否有返回结果:
db.你的集合名.aggregate([ { $group: { _id: "$你的字段名", count: { $sum: 1 } } } ])
如果该命令返回空,说明集合无数据,或字段名拼写/大小写错误(MongoDB区分大小写)。
3. 检查集合与字段名称准确性
- 确保传入的
collectionName与MongoDB中的集合名称完全一致(区分大小写)。 - 确保
fieldName与文档中实际存在的字段拼写、大小写完全匹配。
4. 调试原始聚合结果
在代码中打印原始聚合结果,排查映射问题:
// 在获取mappedResults前添加 System.out.println("原始聚合结果:" + result.getRawResults());
若原始结果有数据但映射后为空,需再次检查字段映射配置。
内容的提问来源于stack exchange,提问作者Cezar Marcu
相关产品推荐
相关产品推荐

