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

MongoDB聚合:多字段去重分组并统计数量的实现

按品牌分组统计汽车文档(含去重逻辑)

嘿,我明白你的需求了——你有一组汽车文档,想要按make(品牌)分组,还得支持按make+model去重后再统计总数,最终输出成指定的makes数组格式。下面分两种场景给你解决方案,不管是用MongoDB处理数据库文档,还是前端纯JS数组都能搞定:

场景1:统计每个品牌的总文档数(不考虑车型重复)

如果你只是想统计每个品牌下的所有文档数量(比如Toyota的3条记录全部计入),用MongoDB的聚合框架可以这么写:

db.cars.aggregate([
  // 第一步:按品牌分组,统计该品牌下的文档总数
  {
    $group: {
      _id: "$make",
      total: { $sum: 1 }
    }
  },
  // 第二步:把字段名改成你要的格式(_id转name,保留total)
  {
    $project: {
      _id: 0,
      name: "$_id",
      total: 1
    }
  },
  // 第三步:把所有品牌统计结果包装成makes数组
  {
    $group: {
      _id: null,
      makes: { $push: "$$ROOT" }
    }
  },
  // 最后去掉多余的_id字段
  {
    $project: {
      _id: 0,
      makes: 1
    }
  }
])

运行结果:

{
  "makes": [
    { "name": "Toyota", "total": 3 },
    { "name": "Lexus", "total": 1 }
  ]
}

场景2:统计每个品牌下的唯一车型数(先按品牌+车型去重)

如果你的需求是先去掉重复的品牌+车型组合,再统计每个品牌有多少种独特车型,调整一下聚合管道就行:

db.cars.aggregate([
  // 第一步:先按品牌+车型去重,只保留唯一组合
  {
    $group: {
      _id: { make: "$make", model: "$model" }
    }
  },
  // 第二步:按品牌分组,统计该品牌下的唯一车型数量
  {
    $group: {
      _id: "$_id.make",
      total: { $sum: 1 }
    }
  },
  // 第三步:整理字段格式
  {
    $project: {
      _id: 0,
      name: "$_id",
      total: 1
    }
  },
  // 第四步:包装成makes数组
  {
    $group: {
      _id: null,
      makes: { $push: "$$ROOT" }
    }
  },
  // 去掉多余的_id
  {
    $project: {
      _id: 0,
      makes: 1
    }
  }
])

运行结果:

{
  "makes": [
    { "name": "Toyota", "total": 2 }, // Prius和Yaris两种独特车型
    { "name": "Lexus", "total": 1 }
  ]
}

纯JavaScript前端处理方案

如果你的数据是前端的JS数组,不用数据库,用reduce也能轻松实现:

场景1:统计品牌总文档数

const cars = [
  { _id: 1, make: 'Toyota', model: 'Prius' },
  { _id: 2, make: 'Toyota', model: 'Prius' },
  { _id: 3, make: 'Toyota', model: 'Yaris' },
  { _id: 4, make: 'Lexus', model: 'RX400' }
];

const result = cars.reduce((acc, car) => {
  // 找当前品牌是否已经在统计列表里
  const existingBrand = acc.makes.find(item => item.name === car.make);
  if (existingBrand) {
    existingBrand.total += 1;
  } else {
    // 不在的话新增一条统计记录
    acc.makes.push({ name: car.make, total: 1 });
  }
  return acc;
}, { makes: [] });

console.log(result);

场景2:统计品牌下的唯一车型数

const cars = [
  { _id: 1, make: 'Toyota', model: 'Prius' },
  { _id: 2, make: 'Toyota', model: 'Prius' },
  { _id: 3, make: 'Toyota', model: 'Yaris' },
  { _id: 4, make: 'Lexus', model: 'RX400' }
];

// 第一步:用Set去重品牌+车型组合
const uniqueModelPairs = [...new Set(cars.map(car => `${car.make}-${car.model}`))];

// 第二步:统计每个品牌的唯一车型数量
const result = uniqueModelPairs.reduce((acc, pair) => {
  const brand = pair.split('-')[0];
  const existingBrand = acc.makes.find(item => item.name === brand);
  if (existingBrand) {
    existingBrand.total += 1;
  } else {
    acc.makes.push({ name: brand, total: 1 });
  }
  return acc;
}, { makes: [] });

console.log(result);

这样不管是数据库端还是前端,都能完美匹配你的需求啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:27:03