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

Node.js+Mongoose+MongoDB用Switch Case实现点赞点踩功能失败问题

问题汇总

  1. Schema定义错误:usersLiked、usersDisliked字段类型设置为String,无法存储用户ID数组,且likes、dislikes没有设置默认值0,会导致数值计算异常。
  2. 模型引用错误:代码开头导入的是Sauce模型,但实际操作调用的是未定义的Book对象。
  3. 数据库操作逻辑错误:findOne是查询方法,不能直接执行更新逻辑,你需要使用更新类方法(如updateOne),且MongoDB更新操作符不能直接放在findOne的then回调中。
  4. 查询条件错误:MongoDB默认主键字段为_id,你使用{ bookId }作为查询条件无法匹配到对应文档,需要改为{ _id: bookId }。
  5. 操作符语法错误:将node层变量like错误添加$前缀识别为文档字段,$in判断时没有给文档数组字段添加$前缀,语法不生效。
  6. 缺失边界逻辑:没有判断用户重复点赞/切换点赞状态的场景,会导致计数异常。

修正后的代码

1. 修正Schema定义

const bookSchema = mongoose.Schema({
  userIdRegister: { type: String, required: true },
  title: { type: String, required: true },
  author: { type: String, required: true },
  description: { type: String, required: true },
  mainperson: { type: String, required: true },
  imageUrl: { type: String, required: true },
  pages: { type: Number, required: true },
  likes: { type: Number, required: false, default: 0 },
  dislikes: { type: Number, required: false, default: 0 },
  usersLiked: { type: [String], required: false, default: [] },
  usersDisliked: { type: [String], required: false, default: [] },
});
// 导出模型名为Book
module.exports = mongoose.model('Book', bookSchema);

2. 修正点赞逻辑代码

// 导入正确的Book模型
const Book = require("../models/Book_models");

exports.addAVote = async (req, res, next) => {
  try {
    const like = req.body.like;
    const userId = req.body.userId;
    const bookId = req.params.id;

    // 先查询当前书籍的点赞状态
    const book = await Book.findOne({ _id: bookId });
    if (!book) return res.status(404).json({ error: "书籍不存在" });

    let updateOp = {};
    switch (like) {
      // 点赞逻辑:先判断用户是否已经点踩,是则先移除点踩记录,再加点赞
      case 1:
        if (book.usersDisliked.includes(userId)) {
          updateOp = {
            $inc: { dislikes: -1, likes: 1 },
            $pull: { usersDisliked: userId },
            $push: { usersLiked: userId }
          };
        } else if (!book.usersLiked.includes(userId)) {
          updateOp = {
            $inc: { likes: 1 },
            $push: { usersLiked: userId }
          };
        }
        break;
      // 点踩逻辑:先判断用户是否已经点赞,是则先移除点赞记录,再加点踩
      case -1:
        if (book.usersLiked.includes(userId)) {
          updateOp = {
            $inc: { likes: -1, dislikes: 1 },
            $pull: { usersLiked: userId },
            $push: { usersDisliked: userId }
          };
        } else if (!book.usersDisliked.includes(userId)) {
          updateOp = {
            $inc: { dislikes: 1 },
            $push: { usersDisliked: userId }
          };
        }
        break;
      // 取消投票逻辑:判断用户在哪个数组里,移除对应记录
      case 0:
        if (book.usersLiked.includes(userId)) {
          updateOp = {
            $inc: { likes: -1 },
            $pull: { usersLiked: userId }
          };
        } else if (book.usersDisliked.includes(userId)) {
          updateOp = {
            $inc: { dislikes: -1 },
            $pull: { usersDisliked: userId }
          };
        }
        break;
      default:
        return res.status(400).json({ error: "无效的投票参数" });
    }

    // 执行更新操作
    await Book.updateOne({ _id: bookId }, updateOp);
    res.status(200).json({ message: "投票成功" });
  } catch (error) {
    console.log("big problem", error);
    res.status(400).json({ error });
  }
};

内容的提问来源于stack exchange,提问作者RoosDev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:45:04