调用点赞接口后,获取博客接口返回重复点赞条目问题咨询
问题原因分析
这个问题的核心有两个点,咱们一个个拆解:
1. 点赞接口混用了async/await和回调函数
你写的likeBlog接口里,同时给findByIdAndUpdate加了await和回调函数,这是Mongoose的错误用法!
Mongoose的规则很明确:如果给方法传了回调函数,它就会直接执行操作并调用回调,不会返回Promise;反之,如果不传回调,才会返回Promise供await使用。你这种混用的写法,在部分Mongoose版本里会触发两次更新操作:一次走回调逻辑,一次走Promise的await逻辑。
所以你调用一次点赞接口时,数据库里的likes数组被$push了两次相同的用户对象——而接口返回的是第一次更新后的结果(只有1条like),等你调用getBlogByID时,数据库里已经存了两条重复的like,自然就返回两条了。
2. 缺少点赞去重逻辑
退一步说,就算修复了混用问题,原来用$push的写法也允许同一个用户重复点赞,会导致likes数组出现重复项,这显然不符合点赞功能的常规需求。
修复方案
首先修复点赞接口的写法(去掉混用,加上去重)
把async/await和回调二选一,这里推荐用更简洁的async/await,同时把$push换成$addToSet(MongoDB的原生操作符,只会添加数组中不存在的元素,自动实现去重):
exports.likeBlog = async (req, res) => { const blog_id = req.params.blog_id; const user_id = req.body.user_id; try { // 用$addToSet替代$push,确保同一用户的点赞只会被添加一次 const newBlog = await Blog.findByIdAndUpdate( blog_id, { $addToSet: { likes: { user: user_id } } }, { new: true } // 配置返回更新后的最新文档 ); console.log(newBlog); res.json(newBlog); } catch (err) { res.status(422).json(err); } };
可选:优化获取博客接口(支持点赞用户信息的关联查询)
如果你想在获取博客时,同时拿到点赞用户的详细信息(而不是只显示ObjectId),可以给populate添加嵌套关联查询:
exports.getBlogByID = async (req, res) => { const blog_id = req.params.blog_id; try { const blog = await Blog.findById(blog_id) .populate("comments") .populate("user") .populate("likes.user"); // 新增这行,关联查询点赞的用户信息 console.log(blog); res.json(blog); } catch (error) { res.status(401).json(error); } };
内容的提问来源于stack exchange,提问作者thatman303
相关产品推荐
相关产品推荐

