Spring Data MongoTemplate多字段去重聚合查询遇空结果求助
Spring Data MongoTemplate聚合去重返回空结果修复
问题背景
作为MongoDB聚合查询新手,需在userDetails集合中对userId和user字段执行去重操作。在Robo 3T中执行以下聚合语句可得到正确结果,但对应的Spring Data MongoTemplate代码返回空结果:
原MongoDB聚合语句
db.userDetails.aggregate([ {"$match" : {zip:"52034", city:"Delhi"}}, // 按userId和user分组实现去重 {"$group" : {_id : {userId:"$userId", user:"$user"}}}, // 整理输出结构 {"$project" : {_id:0, userId:"$_id.userId", user:"$_id.user"}} ])
出错的Java代码
MatchOperation matchOperation = Aggregation.match( new Criteria("zip").is(zipCode).and("city").is(cityName)); GroupOperation groupOperation = new GroupOperation(Fields.fields("userId", "user")); ProjectionOperation projectionOperation = Aggregation.project().andExclude("_id").and("userId").nested( Fields.fields("_id.userId")) .and("user").nested(Fields.fields("_id.user")); Aggregation aggregation = Aggregation.newAggregation(matchOperation, groupOperation, projectionOperation); AggregationResults<UserDTO> result = mongoTemplate.aggregate(aggregation, UserDetails.class, UserDTO.class);
版本信息:Spring Data MongoDB 3.0.7,Driver 4.0.4
问题原因
出错核心在于ProjectionOperation的写法错误:使用nested()方法会创建嵌套文档结构,而非从_id中提取字段值映射到顶级字段,导致最终返回的文档结构与UserDTO不匹配,因此无法正确映射得到结果。
修正后的代码
MatchOperation matchOperation = Aggregation.match( new Criteria("zip").is(zipCode).and("city").is(cityName)); // GroupOperation写法正确,无需修改 GroupOperation groupOperation = new GroupOperation(Fields.fields("userId", "user")); // 修正ProjectionOperation:直接提取_id中的字段映射为顶级字段 ProjectionOperation projectionOperation = Aggregation.project() .andExclude("_id") .and("_id.userId").as("userId") .and("_id.user").as("user"); Aggregation aggregation = Aggregation.newAggregation(matchOperation, groupOperation, projectionOperation); AggregationResults<UserDTO> result = mongoTemplate.aggregate(aggregation, UserDetails.class, UserDTO.class);
说明
修正后的ProjectionOperation会生成与原MongoDB聚合语句一致的$project阶段:
{"$project" : {_id:0, userId:"$_id.userId", user:"$_id.user"}}
这样返回的文档结构能正确匹配UserDTO的字段,即可得到预期的去重结果。
内容的提问来源于stack exchange,提问作者user2068260
相关产品推荐
相关产品推荐

