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
相关产品推荐
相关产品推荐

