Mongoose模型populate填充后后续访问未保持填充状态是什么原因?
关于Mongoose populate无法持久化的问题解答
根本原因
Mongoose的populate是仅在查询阶段生效的内存级临时操作,不会将关联文档的完整内容写入到你的formula集合中。你在新增评论时执行的populate只是给当前内存里的theFormula对象临时填充了评论完整数据,调用save()存到MongoDB的时候,comments字段还是只会存关联的Comment文档ObjectId,不会存完整的评论对象,所以后续新的查询请求拿到的自然只有ID数组。
解决方法
两种常用方案选其一即可:
方案1:查询时手动调用populate
你当前的详情页路由中,获取formula数据时没有添加populate逻辑,修改你的查询代码即可。如果你是在verifyID中间件中查询的formula,修改中间件里的查询语句:
// 原来的查询 const theFormula = await formulaModel.findById(req.params.id); // 修改为带populate的查询 const theFormula = await formulaModel.findById(req.params.id).populate('comments');
如果是在当前路由中查询,同理添加.populate('comments')即可。
方案2:配置Schema自动populate(适合每次查formula都需要带评论的场景)
在formulaSchema中添加pre查询中间件,每次触发find相关查询时自动填充comments字段:
// 在formulaSchema定义后、导出model前添加这段代码 formulaSchema.pre(/^find/, function(next) { this.populate('comments'); next(); });
额外代码优化建议
你当前新增评论的代码执行顺序可以调整,避免潜在问题:先保存评论,再将评论ID推入formula的comments数组,再保存formula,调整后逻辑更严谨:
router.post('/:id/comments', verifyComment, wrapAsync(async function(req, res, next) { const { id } = req.params; const theFormula = await formulaModel.findById(id); const comment = new commentModel(req.body.comment); // 先保存评论 await comment.save(); // 再推入数组 theFormula.comments.push(comment); // 保存formula await theFormula.save(); res.redirect(`/details/${id}`); }))
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

