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

Node.js中使用Mongoose按appid去重并返回完整文档的方法

实现Mongoose中按appid去重并返回完整文档的方法

嘿,这个问题我之前也碰到过!distinct确实只能返回单个字段的数组,没法拿到完整的文档结构,不过咱们用MongoDB的聚合管道就能完美解决,给你两种实用的实现方式,直接在Mongoose里就能用:

方法一:用$group + $replaceRoot快速获取去重完整文档

这是最简洁的方式,核心思路是按appid分组,每组保留第一个(或最后一个)完整文档,再把分组后的结果还原成标准文档格式:

// 导入你的Mongoose模型
const GameModel = require('./models/game');

async function getUniqueGamesByAppid() {
  try {
    const uniqueDocs = await GameModel.aggregate([
      // 可选:先按_id倒序,确保每组保留最新的文档
      { $sort: { _id: -1 } },
      // 按appid分组,用$$ROOT指代当前整个文档,$first取每组第一条
      {
        $group: {
          _id: "$appid",
          doc: { $first: "$$ROOT" }
        }
      },
      // 将分组后的doc字段作为根文档返回,还原成原始文档结构
      {
        $replaceRoot: { newRoot: "$doc" }
      }
    ]);
    return uniqueDocs;
  } catch (err) {
    console.error('查询出错:', err);
    throw err;
  }
}

// 调用示例
getUniqueGamesByAppid()
  .then(docs => console.log('去重后的文档:', docs))
  .catch(err => process.exit(1));

如果想保留每组里最早的文档,把$first换成$last即可;要是有特定排序需求,调整前面的$sort阶段就行(比如按name排序)。

方法二:自定义返回字段的去重查询

如果不需要返回完整文档,或者需要对返回字段做定制,你可以在分组阶段明确指定要保留的字段,再重组文档:

async function getCustomUniqueDocs() {
  const result = await GameModel.aggregate([
    { $sort: { appid: 1, _id: -1 } },
    {
      $group: {
        _id: "$appid",
        originalId: { $first: "$_id" },
        appid: { $first: "$appid" },
        name: { $first: "$name" },
        code: { $first: "$code" }
      }
    },
    // 重新映射字段,把originalId改回_id,还原成熟悉的文档结构
    {
      $project: {
        _id: "$originalId",
        appid: 1,
        name: 1,
        code: 1
      }
    }
  ]);
  return result;
}

性能优化提示

如果你的数据集很大,建议给appid字段建立索引,这样聚合分组的效率会大幅提升:

// 在你的Mongoose模型定义中添加索引
const gameSchema = new mongoose.Schema({
  appid: Number,
  name: String,
  code: String
});

// 给appid建立单字段索引
gameSchema.index({ appid: 1 });

const GameModel = mongoose.model('Game', gameSchema);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:30:59