如何在Mongoose查询填充中为字段设置别名
Mongoose填充后为关联字段子字段设置别名的实现方法
针对你的需求,这里提供三种可行的实现方式:
方法一:查询后手动映射字段
这是最直接简单的方式,先完成填充查询,再遍历结果重新构造author对象的字段:
const postData = await postModel .find({ author: id }) .populate('author', '_id fullname email updatedAt') // 只拉取需要的字段,减少数据传输 .sort({ updatedAt: -1 }); // 手动转换字段别名 const formattedData = postData.map(post => { const plainPost = post.toObject(); // 把Mongoose文档转为普通JS对象 return { ...plainPost, author: { user_id: plainPost.author._id, user_fullname: plainPost.author.fullname, user_email: plainPost.author.email, user_updated: plainPost.author.updatedAt } }; }); console.log(formattedData);
方法二:用聚合管道在数据库端处理
如果数据量较大,推荐用聚合管道替代populate,在数据库层面完成字段别名转换,性能更优:
const formattedData = await postModel.aggregate([ // 匹配目标作者的帖子 { $match: { author: mongoose.Types.ObjectId(id) } }, // 关联作者集合 { $lookup: { from: 'authors', // 注意这里是作者集合的名称,要和Author模型的collection属性一致 localField: 'author', foreignField: '_id', as: 'author' } }, // 将$lookup返回的数组转为单个对象 { $unwind: '$author' }, // 投影并设置字段别名 { $project: { content: 1, createdAt: 1, updatedAt: 1, 'author.user_id': '$author._id', 'author.user_fullname': '$author.fullname', 'author.user_email': '$author.email', 'author.user_updated': '$author.updatedAt' } }, // 按更新时间倒序排序 { $sort: { updatedAt: -1 } } ]); console.log(formattedData);
方法三:给Author模型添加虚拟属性(全局复用)
如果需要在多个查询场景中复用这个别名格式,可以给Author模型定义虚拟属性,让填充结果自动携带别名字段:
先修改Author模型的Schema:
const authorSchema = new mongoose.Schema({ username: String, fullname: String, email: String, createdAt: Date, updatedAt: Date }, { toJSON: { virtuals: true }, // 转JSON时包含虚拟属性 toObject: { virtuals: true } // 转普通对象时包含虚拟属性 }); // 定义对应别名的虚拟属性 authorSchema.virtual('user_id').get(function () { return this._id; }); authorSchema.virtual('user_fullname').get(function () { return this.fullname; }); authorSchema.virtual('user_email').get(function () { return this.email; }); authorSchema.virtual('user_updated').get(function () { return this.updatedAt; }); const Author = mongoose.model('Author', authorSchema);
之后查询时,填充时排除不需要的原始字段即可:
const postData = await postModel .find({ author: id }) .populate({ path: 'author', select: '-_id -username -createdAt' // 排除不需要的原始字段,只保留虚拟属性和需要的内容 }) .sort({ updatedAt: -1 }); console.log(postData);
内容的提问来源于stack exchange,提问作者Epple
相关产品推荐
相关产品推荐

