Spring Boot MongoDB执行Distinct后如何返回带指定字段的对象
问题原因
你当前调用的distinct()方法的原生设计就是仅返回指定去重字段的取值集合,因此只会得到serialNumber的字符串列表,无法直接返回包含指定字段的文档对象。要实现按serialNumber去重同时保留指定返回字段,需要使用MongoDB的聚合查询实现。
实现方案
1. 原生MongoDB聚合逻辑
聚合管道共3个阶段,适配MongoDB 3.4.6版本:
db.Account.aggregate([ // 第一步:仅保留需要查询的字段,减少计算量 { $project: { serialNumber: 1, "account.accountName": 1, _id: 0 } }, // 第二步:按serialNumber分组实现去重,取分组内第一条数据的accountName { $group: { _id: "$serialNumber", accountName: {$first: "$account.accountName"} } }, // 第三步:调整返回结构,匹配Account类的字段定义 { $project: { _id: 0, serialNumber: "$_id", "account.accountName": "$accountName" } } ])
注意:如果同一个
serialNumber对应多个不同的account.accountName,可以根据业务需求替换$first为$last(取最新一条)、$addToSet(收集该serialNumber下所有不重复的accountName)等操作符。
2. Spring Data MongoDB对应代码
适配Spring Boot 1.4.2自带的Spring Data MongoDB版本:
import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationResults; import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; // 构造聚合管道 Aggregation aggregation = newAggregation( // 筛选需要的字段 project("serialNumber", "account.accountName"), // 按serialNumber分组去重 group("serialNumber") .first("account.accountName").as("accountName"), // 调整返回结构匹配Account类 project() .and("_id").as("serialNumber") .and("accountName").as("account.accountName") .andExclude("_id") ); // 执行聚合查询,结果映射为Account对象 AggregationResults<Account> results = mongoTemplate.aggregate( aggregation, "Account", Account.class ); // 获取最终结果列表 List<Account> accounts = results.getMappedResults();
内容的提问来源于stack exchange,提问作者Thanigai
相关产品推荐
相关产品推荐

