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

如何在MongoDB中用@Query注解实现单字段去重查询并支持分页

方案1:MongoDB聚合查询(数据库层面去重,推荐)

直接在查询阶段完成去重,性能更高,分页逻辑也更准确,你可以把原Repository方法替换为使用@Aggregation注解的聚合查询:

@Aggregation(pipeline = {
    "{$match: {$and :[{'submitTime':{$ne:null}}, {'gameId': :#{#gameId}} ]}}",
    "{$sort: {'score': -1, 'timeTaken': 1, 'submitTime': 1}}",
    "{$group: {_id: '$userId', play: {$first: '$$ROOT'}}}",
    "{$replaceRoot: {newRoot: '$play'}}",
    "{$sort: {'score': -1, 'timeTaken': 1, 'submitTime': 1}}"
})
Flux<Play> getDistinctWinners(@Param("gameId") String gameId, Pageable pageable);

逻辑说明:

  • 先按你原有条件过滤符合要求的记录
  • 按原排名规则排序,保证同一个用户最优的记录排在该用户所有记录的最前面
  • 按userId分组,取每组第一条记录作为该用户的代表
  • 把嵌套的Play数据提取为根文档,直接映射为你的实体类
  • 最后重新做全局排序,配合Pageable自动完成分页的跳过、限制逻辑

方案2:Flux流层面去重(适合小数据量场景)

如果不想修改原查询逻辑,可以直接对返回的Flux流按userId做去重,只会保留同一个用户第一次出现的记录(也就是排序后的最优记录):

// 业务层处理逻辑
public Flux<Play> getDistinctWinners(String gameId, Pageable pageable) {
    return playRepository.getWinners(gameId, pageable)
            .distinct(Play::getUserId);
}

注意该方案是在内存中做过滤,如果原分页查询返回的结果里同一个用户有多条记录,会导致最终返回的条数小于你设定的pageSize,数据量大时性能低于聚合方案。


内容的提问来源于stack exchange,提问作者Powsikan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:06:04