You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用点赞接口后,获取博客接口返回重复点赞条目问题咨询

问题原因分析

这个问题的核心有两个点,咱们一个个拆解:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:12:36