如何在Mongoose中获取数组内的关联文档详情?
查询分类时返回关联文章的完整信息
我有Post和Category两个Mongoose模型,Category的posts数组存储Post的ObjectId,模型定义如下:
Category 模型
const mongoose = require('mongoose'); const CategorySchema = new mongoose.Schema( { name: { type: String, required: true, }, color: { type: String, required: true, }, posts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post', required: false, }], createdAt: { type: Date, default: Date.now, } }, { timestamps: true } ); module.exports = mongoose.model("Category", CategorySchema);
Post 模型
const mongoose = require('mongoose'); const PostSchema = new mongoose.Schema( { title: { type: String, required: true, }, img: { type: String, required: true, }, category: { type: mongoose.Schema.Types.ObjectId, ref: "Category", }, desc: { type: String, required: false, }, createdAt: { type: Date, default: Date.now, } }, { timestamps: true } ); module.exports = mongoose.model("Post", PostSchema);
当前的查询分类控制器代码如下,请求后返回的posts数组仅显示Post的ObjectId:
const Category = require('../../models/Category'); class FindCategory { async find(req, res) { const { id } = req.params; try { const category = await Category.findById(id); return res.status(200).json(category); } catch (err) { return res.status(500).json(err); } } } module.exports = new FindCategory();
希望返回的posts数组包含每个Post的完整信息,示例如下:
{ "_id": "63ac925d872445065a588f61", "name": "Games", "color": "#ff914d", "posts": [ {"title": "red dead", "img": "example.png", "category": "games", "desc": "test"} ], "createdAt": "2022-12-28T19:00:45.847Z", "updatedAt": "2022-12-28T19:49:47.119Z", "__v": 0 }
解决方法
使用Mongoose的populate()方法,它可以将文档中存储的ObjectId替换为对应的关联文档内容。修改控制器中的查询语句即可实现需求:
修改后的控制器代码
const Category = require('../../models/Category'); class FindCategory { async find(req, res) { const { id } = req.params; try { // 使用populate填充posts字段对应的Post文档 // 第二个参数可选,用于指定只返回需要的字段,避免返回冗余数据 const category = await Category.findById(id) .populate('posts', 'title img category desc'); return res.status(200).json(category); } catch (err) { return res.status(500).json(err); } } } module.exports = new FindCategory();
说明
populate('posts')会把posts数组里的所有ObjectId替换为完整的Post文档- 如果不需要返回Post的所有字段,可以在第二个参数里指定需要的字段(用空格分隔),比如示例中的
'title img category desc',这样返回的结构就和你期望的一致 - 确保模型中
posts字段的ref属性正确指向了Post模型,否则填充会失败
内容的提问来源于stack exchange,提问作者Routfin
相关产品推荐
相关产品推荐

