Node.js电影应用如何实现每个用户对单条电影帖子仅点赞一次
实现单用户单电影帖子仅可点赞一次的方案
1. 调整Movies模型结构
原有模型仅记录点赞总数,没有存储点赞用户标识,需要新增likedBy字段存储所有点赞过该帖子的用户ID:
const mongoose = require('mongoose'); const moviesSchema = new mongoose.Schema({ title: { type: String, required: true }, description: { type: String, required: true }, link: { type: String, required: true }, moviesData: { type: Date, required: true, default: Date.now // 原代码写Date.now()会导致初始化时固定时间,这里修正为传函数引用 }, user: { type: String, required: true, }, userName: { type: String, required: false }, likes: { type: Number, default: 0 }, // 新增点赞用户列表字段 likedBy: { // 如果你的用户ID是MongoDB默认ObjectId类型,用下面两行配置 type: [mongoose.Schema.Types.ObjectId], ref: 'User', // 这里对应你的用户模型名称,按需修改 // 如果你的用户ID是自定义字符串类型,替换上面两行为:type: [String], default: [] } }); module.exports = mongoose.model('Movie', moviesSchema);
2. 改造点赞接口逻辑
首先确保你的接口已经接入用户鉴权(如JWT鉴权),可以从req对象中拿到当前登录用户的ID。推荐使用MongoDB原子操作实现,避免并发请求导致的重复点赞问题:
// 先引入你的鉴权中间件,保证只有登录用户可以调用点赞接口,且能从req.user拿到用户信息 const auth = require('../你的鉴权中间件文件路径'); // Add like to movie router.patch('/admin/like/:id', auth, async (req, res) => { console.log("POST LIKE to movie") const movieId = req.params.id; // 这里的用户ID字段根据你的鉴权逻辑调整,部分场景下是req.user._id const currentUserId = req.user.id; try { const updateResult = await Movie.updateOne( // 查询条件:电影存在 + 当前用户未点赞 { _id: movieId, likedBy: { $ne: currentUserId } }, { // 将当前用户加入点赞列表 $push: { likedBy: currentUserId }, // 点赞数+1 $inc: { likes: 1 } } ); if (updateResult.matchedCount === 0) { // 区分两种匹配失败的场景 const movieExists = await Movie.exists({ _id: movieId }); if (!movieExists) { return res.status(404).json({ message: "对应的电影帖子不存在" }); } return res.status(400).json({ message: "你已经对该帖子点过赞了" }); } // 返回最新点赞数 const updatedMovie = await Movie.findById(movieId, { likes: 1 }); res.status(200).json({ message: "点赞成功", number_of_likes: updatedMovie.likes }); } catch (error) { res.status(400).json({ message: "An error has occurred", error: error }); } })
补充说明
- 若不需要单独维护
likes字段,可以直接删除该字段,后续需要展示点赞数时直接读取likedBy数组的长度即可,避免出现数据不一致问题 - 原子操作的实现方式比先查后改的性能更高,也能避免同一用户短时间内多次请求导致的重复点赞漏洞
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

