Node.js+Mongoose+MongoDB用Switch Case实现点赞点踩功能失败问题
问题汇总
- Schema定义错误:
usersLiked、usersDisliked字段类型设置为String,无法存储用户ID数组,且likes、dislikes没有设置默认值0,会导致数值计算异常。 - 模型引用错误:代码开头导入的是
Sauce模型,但实际操作调用的是未定义的Book对象。 - 数据库操作逻辑错误:
findOne是查询方法,不能直接执行更新逻辑,你需要使用更新类方法(如updateOne),且MongoDB更新操作符不能直接放在findOne的then回调中。 - 查询条件错误:MongoDB默认主键字段为
_id,你使用{ bookId }作为查询条件无法匹配到对应文档,需要改为{ _id: bookId }。 - 操作符语法错误:将node层变量
like错误添加$前缀识别为文档字段,$in判断时没有给文档数组字段添加$前缀,语法不生效。 - 缺失边界逻辑:没有判断用户重复点赞/切换点赞状态的场景,会导致计数异常。
修正后的代码
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
相关产品推荐
相关产品推荐

