MongoDB如何按code字段去重获取唯一transfer文档?
MongoDB聚合实现:每个code仅保留一条文档
针对你需要从transfer集合中获取每个唯一数值型code对应一条文档的需求,以下是几种高效的聚合实现方案,解决你之前$group阶段未完成、merge/group未达预期的问题:
方案1:任意保留每组一条文档(最简版)
如果不需要特定规则,仅需每个code对应任意一条文档,直接用$group配合$first或$last即可,无需多余的$unwind(除非你的code字段嵌套在数组中,这种情况才需要先$unwind数组)。
db.transfer.aggregate([ // 按code分组,取每组第一条完整文档 { $group: { _id: "$code", doc: { $first: "$$ROOT" } // 使用$last则取每组最后一条 } }, // 将嵌套的doc还原为顶层文档结构 { $replaceRoot: { newRoot: "$doc" } } ])
方案2:按规则保留特定文档(如最新/最早)
如果需要按时间或其他字段筛选,比如保留每个code对应的最新文档,先通过$sort排序,再分组取第一条:
db.transfer.aggregate([ // 按更新时间倒序排序,最新的文档排在每组最前面 { $sort: { updateTime: -1 } }, { $group: { _id: "$code", doc: { $first: "$$ROOT" } } }, { $replaceRoot: { newRoot: "$doc" } } ])
方案3:自定义保留字段(无需完整文档)
如果只需要保留部分字段而非完整文档,可以在$group中直接指定字段,再通过$project调整结构:
db.transfer.aggregate([ { $group: { _id: "$code", transferId: { $first: "$_id" }, amount: { $first: "$amount" }, createTime: { $first: "$createTime" } } }, // 映射回原字段名(可选,根据需求调整) { $project: { _id: "$transferId", code: "$_id", amount: 1, createTime: 1 } } ])
常见问题说明
- 如果你之前用了
$unwind但code是顶层字段,这个阶段完全多余,会导致数据重复处理,直接移除即可。 - 使用
merge阶段未达预期,大概率是因为merge更适合合并数据而非去重分组,针对单集合的同code去重,$group是最直接的方案。
内容的提问来源于stack exchange,提问作者jecorrales
相关产品推荐
相关产品推荐

