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

如何使用Mongo聚合根据model字段获取唯一文档

解决MongoDB Cars集合按model字段去重的方法

需求:从Cars集合中按model字段去重,每个model仅保留一个对应文档,集合示例数据如下:

[
  { _id:'12345', model:'Honda' },
  { _id:'12346', model:'Honda' },
  { _id:'12347', model:'Honda' },
  { _id:'12348', model:'Toyota' },
  { _id:'12349', model:'Volkswagen' },
  { _id:'12350', model:'Volkswagen' },
]

方法1:聚合管道(高效推荐)

用$group按model分组,每组保留第一个文档,最后还原文档结构:

db.Cars.aggregate([
  {
    $group: {
      _id: "$model", // 以model为分组依据
      doc: { $first: "$$ROOT" } // 保留每组的第一个完整文档
    }
  },
  {
    $replaceRoot: { newRoot: "$doc" } // 将嵌套的doc转为根文档输出
  }
])

如果想保留每组最后一个文档,把$first换成$last即可,也可以根据需求指定保留特定字段。

方法2:先拿唯一model再逐个查询

先获取所有不重复的model值,再遍历查询每个model的第一个文档:

// 获取所有唯一model值
const uniqueModels = db.Cars.distinct("model");

// 遍历输出每个model的第一个匹配文档
uniqueModels.forEach(model => {
  console.log(db.Cars.findOne({ model: model }));
});

这种方法适合需要自定义筛选逻辑的场景,但数据量大时性能不如聚合管道。

方法3:创建唯一索引(永久杜绝重复)

如果想彻底避免后续插入重复model的文档,先清理现有重复数据,再创建唯一索引:

// 第一步:删除重复数据,保留每个model的第一个文档
db.Cars.aggregate([
  { $group: { _id: "$model", ids: { $push: "$_id" }, count: { $sum: 1 } } },
  { $match: { count: { $gt: 1 } } }
]).forEach(doc => {
  doc.ids.shift(); // 移除第一个id,保留该文档
  db.Cars.deleteMany({ _id: { $in: doc.ids } });
});

// 第二步:创建model字段的唯一索引
db.Cars.createIndex({ model: 1 }, { unique: true });

创建索引后,再插入相同model的文档会直接报错,从根源解决重复问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:06:27