使用Mongoose $inc操作符统计文章浏览量不生效问题求助
问题根因
你代码中的findOneAndUpdate是异步方法,返回Promise对象,你没有等待该异步操作执行完成就触发了后续的查询逻辑,导致更新请求还没写入数据库就执行了查询,最终viewCount自增逻辑没有生效。
同时你分开写更新和查询的逻辑会多触发一次数据库请求,findOneAndUpdate本身支持配置返回更新后的最新文档,直接复用即可。
修复代码
这里推荐使用更易维护的async/await写法:
router.get('/post/:slug', async (req, res) => { try { // 单条请求完成更新+查询,new参数指定返回更新后的文档 const post = await Post.findOneAndUpdate( { slug: req.params.slug }, { $inc: { viewCount: 1 } }, { new: true } ) .populate({path: 'comments', populate: {path: 'user', model: 'users'}}) .populate('user'); const categories = await Category.find({}); res.render('home/post', { post, categories }); } catch (err) { // 可自行替换为你的项目错误处理逻辑 console.error('页面加载失败:', err); res.status(500).send('页面加载失败'); } });
如果需要保留原有的Promise链式写法,调整后如下:
router.get('/post/:slug',(req, res) => { Post.findOneAndUpdate( {slug : req.params.slug}, {$inc : {viewCount : 1}}, {new: true} ) .populate({path: 'comments', populate: {path: 'user', model: 'users'}}) .populate('user') .then(post => { return Category.find({}) .then(categories => { res.render('home/post', {post, categories}); }); }) .catch(err => { console.error('加载失败:', err); res.status(500).send('加载失败'); }); });
额外优化提示
你当前Schema中date字段的默认值写法存在问题:
date: { type: Date, default: Date.now() },
Date.now()会在服务启动时就执行计算得到固定时间,所有新增文章的发布时间都会是服务启动时间而非文章实际创建时间,改为传函数引用即可:
date: { type: Date, default: Date.now },
内容的提问来源于stack exchange,提问作者exitcode_1
相关产品推荐
相关产品推荐

