You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 13:54:03