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

MongoDB Template如何从重复数据中仅获取单条记录?

问题

我的MongoDB数据库中存在仅_id不同、其余属性完全一致的重复数据,希望通过API仅返回每条重复数据中的一条。例如数据库中有如下结构的文档:

{
  "_id": "39012fh19fh19bf21",
  "propertyId": 12345,
  "type": "STORE"
},
{
  "_id": "69999999111",
  "propertyId": 12345,
  "type": "STORE"
}

我尝试使用聚合分组操作去重,但未能成功。当前的代码实现如下:

val matchOperation = match(nestedCriteria) // 这里是一些基础过滤条件
val sortDirection = Sort.Direction.ASC 
val sortBy = "type"
val page = PageRequest.of(...)

val aggregation = newAggregation(
    matchOperation, sort(Sort.by(sortDirection, sortBy)), skip(page.offset), limit(
        page.pageSize.toLong()
    )
)

return mongoTemplate.aggregate(aggregation, "my_collection", MyCollectionVO::class.java)
    .asFlow()

我曾尝试如下分组操作及其他组合,但均未生效:

val groupOperation = group("propertyId", "type")
    .count().`as`("count")
    .first("_id").`as`("uniqueDocId")

val matchOperation = match(Criteria.where("count").gt(1))

现寻求正确的实现方法。

解决方案

你之前的分组操作只获取了重复计数和单个_id,没有完整保留文档的其他字段,而且错误地筛选了count>1的分组——这会只返回存在重复的分组,而你需要的是所有数据去重后返回,不管有没有重复。

正确的实现思路和代码如下:

val matchOperation = match(nestedCriteria) // 基础过滤条件
val sortDirection = Sort.Direction.ASC 
val sortBy = "type"
val page = PageRequest.of(...)

// 按重复标识字段分组,保留每组第一个完整文档
val groupOperation = group("propertyId", "type")
    .first("$$ROOT").`as`("uniqueDoc") // $$ROOT代表整个原始文档

// 将分组后的文档还原为根节点格式
val replaceRootOperation = replaceRoot("uniqueDoc")

// 排序、分页必须放在去重之后,避免分页结果包含重复数据
val aggregation = newAggregation(
    matchOperation,
    groupOperation,
    replaceRootOperation,
    sort(Sort.by(sortDirection, sortBy)),
    skip(page.offset),
    limit(page.pageSize.toLong())
)

return mongoTemplate.aggregate(aggregation, "my_collection", MyCollectionVO::class.java)
    .asFlow()

关键说明

  • 使用$$ROOT可以直接获取整个原始文档,无需手动逐个指定字段,避免遗漏属性
  • 如果需要精准选择保留哪条重复数据,可以在分组前先按_id或其他业务字段排序,确保first()拿到你想要的条目
  • 分页操作必须放在去重步骤之后,否则会出现分页截断重复数据、导致结果仍有重复或丢失有效数据的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:43:28