Mongoose中无法填充articles字段问题求助
Mongoose Populate 无法填充articles字段的问题排查与解决
嘿,我来帮你搞定这个populate失效的问题!你现在遇到的情况是明明数据库里有对应文章,但调用populate('articles')后返回的却是空数组,咱们一步一步来排查:
先梳理下你的现有代码与数据
你的Schema定义
Category-Article Schema
var category_article_Schema = new Schema({ "article_id": { type: String, required: false, unique: false }, "category": String, "articles": [{ type: mongoose.Schema.Types.ObjectId, ref:'article'}], }); var category_article_Schema = mongoose.model('category_article_Schema', category_article_Schema); module.exports = category_article_Schema;
Article Schema
var articleSchema = new Schema({ "title": { type: String, required: true, unique: false }, "details": String, "username": { type: String, required: true, unique: false }, "postImageUrl": String, "url": String, "categories": [String], "created_at": { type: Date, default: Date.now } }); var article = mongoose.model('article', articleSchema); module.exports = article;
查询函数
function getPostByCategory(req, res, next) { category_article_model.find({category: req.params.name}) //sports .populate('articles') .exec() .then(function(articlesByCategory) { console.log(articlesByCategory); }) .catch(function(err){ console.log('err ', err); }) }
数据库中的实际数据
Article集合数据
[ { "_id": { "$oid": "5b0008ce8787890004989df1" }, "categories": [ "sports", "health" ], "title": "sample", "details": "sample ", "created_at": { "$date": "2018-05-19T11:21:50.837Z" }, "__v": 0 }, { "_id": { "$oid": "5b0087646dda9600049a9a27" }, "categories": [ "sports" ], "title": "sample3333", "details": " sample3333", "created_at": { "$date": "2018-05-19T20:21:56.126Z" }, "__v": 0 } ]
Category_Article集合数据
{ "_id": { "$oid": "5b0087646dda9600049a9a28" }, "category": "sports", "article_id": "5b0087646dda9600049a9a27", "__v": 0 }
当前返回结果
[ { articles: [], _id: 5b0008ce8787890004989df2, category: 'sports', article_id: '5b0008ce8787890004989df1', __v: 0 } ]
问题出在哪?
核心问题就是你的数据库数据和Schema定义不匹配:
- 你在Schema里定义了
articles字段是用来存储关联文章ObjectId的数组,但实际数据库里的category_article文档根本没有这个articles数组!反而用了一个单独的article_id字段存单个文章ID。Mongoose的populate('articles')只会去查找articles数组里的ObjectId,自然找不到任何数据,返回空数组。 - 另外,
article_id这个字段完全是冗余的,它和articles数组的作用重叠,还导致了你维护数据时的混淆。
怎么解决?
1. 先修正数据库里的Category_Article数据
把现有的category_article文档中的article_id值转移到articles数组中,修改后的文档应该是这样的:
{ "_id": { "$oid": "5b0087646dda9600049a9a28" }, "category": "sports", "articles": [ObjectId("5b0087646dda9600049a9a27")], // 把之前的article_id放到这个数组里 "__v": 0 }
如果有多个属于该分类的文章,直接把对应的ObjectId都添加到articles数组就行。
2. 优化你的Schema(推荐)
既然articles数组已经能存储多个关联的文章ID,article_id字段就没用了,删掉它简化Schema:
var category_article_Schema = new Schema({ "category": String, "articles": [{ type: mongoose.Schema.Types.ObjectId, ref:'article'}], }); var category_article_model = mongoose.model('category_article_Schema', category_article_Schema); module.exports = category_article_model;
3. 验证查询结果
修改完数据后,再运行你的getPostByCategory函数,populate('articles')就能正确找到对应的文章数据,返回的结果里articles字段会填充完整的文章信息,不再是空数组啦。
额外小技巧:批量同步分类关联数据
如果你的文章已经有categories字段存储所属分类,你可以写个脚本批量同步category_article集合的数据,不用手动维护:
// 示例脚本:根据文章的categories字段更新category_article集合 Article.find({}).then(articles => { articles.forEach(article => { article.categories.forEach(categoryName => { // 查找或创建对应的分类文档,避免重复添加文章ID CategoryArticle.findOneAndUpdate( { category: categoryName }, { $addToSet: { articles: article._id } }, { upsert: true, new: true } ).exec(); }); }); }).catch(err => console.error(err));
内容的提问来源于stack exchange,提问作者kittu
相关产品推荐
相关产品推荐

