【发布时间】:2022-12-13 06:43:27
【问题描述】:
(请在下面的回答帖子中找到我的解决方案)
希望你过得好。我今天的问题是关于一个喜欢/不喜欢带有nodeJs的简单系统,数据在MongoDB上。
你是什么情况?
-
我得到了 API 后端的实现。前端已经做好了,不用动了。
-
API 的目的是允许人们发布带有一系列参数的辣酱。每个用户都必须登录才能执行任何操作!在此开发阶段,对任何页面执行的任何刷新都会将用户直接送回登录页面。
-
我正在完成我需要完成的最后一项任务:为“喜欢/不喜欢”的简单系统实施路线。该系统具有以下设置:
-
如果用户点击“赞”,前端发送一个“1”数值(以下称为“likeStatus”)
-
如果用户点击“拇指向下”,前端会发送一个“-1”,如 Status
-
如果用户取消点击他们的喜欢/不喜欢,前端发送一个“0” likeStatus
-
当用户点击任一拇指时,用户的 ID 将存储在对象模型中内置的两个数组之一中:usersLiked 或 usersDisliked,具体取决于用户的选择。请注意,这两个数组都包含在“sauce”模型中,因此它们不会出现在用户模型中。
-
在前端,当用户点击任何一个拇指时,另一个拇指是灰色的,以防止他们点击它。用户必须取消单击他们的初始选择才能选择另一个。
你有什么问题?
我的问题是,当用户从“1”或“-1”返回到“0(零)”时,我无法跟踪用户的取消点击。那是因为我不知道如何检查用户在归零之前的位置。对我来说重要的是要确保从正确的数组中删除他并减少正确的计数器而不是两者都或错误的计数器。
在尝试了我在下面描述的内容之后,我正在寻找一种方法来检查:
- userId 存储在哪个数组中(userLiked 或 userDisliked)
或者
- 用户最后的点赞状态是什么(1 或 -1)
到目前为止你尝试了什么?
我想使用 if/else 链来检查 likeStatus 并搜索数组 usersLiked 和 usersDisliked 以查看 userId(此处称为“liker”)是否在其中。如果它在 usersLiked 中,那么我可以递减 likes 计数器,如果 id 在 userDisliked 中则相反。 但是两个数组都被视为“未定义”,因此无法读取。
向我们展示您的代码
到目前为止,我已经构建了类似/不同路线的完整代码:
exports.likeSauce = (req,res,next) =>{ const liker = req.body.userId; let likeStatus = req.body.like; let usersLiked = req.body.usersLiked; let usersDisliked = req.body.usersDisliked; if(likeStatus===1){ sauce.updateOne({_id:req.params.id}, {$inc:{likes:+1},$push:{usersLiked:liker}}) .then(()=>res.status(201).json({message:'you liked this sauce'})) .catch(error=>res.status(400).json({error})) } else if (likeStatus===-1) { sauce.updateOne({_id:req.params.id}, {$inc:{dislikes:+1},$pull:{usersLiked:liker},$push:{usersDisliked:liker}}) .then(()=>res.status(201).json({message:'you disliked this sauce'})) .catch(error=>res.status(400).json({error})) } else if(likeStatus===0){ if(usersLiked.includes(liker)){ sauce.updateOne({_id: req.params.id}, { $inc: { likes: -1}, $pull: { usersLiked:liker}}) } else if (usersDisliked.includes(liker)){ sauce.updateOne({_id: req.params.id}, { $inc: { dislikes: -1}, $pull: { usersDisliked:liker}}) } } }还有什么可能有用的吗?
这是“sauce”模型,它的末尾有两个数组:
const mongoose = require('mongoose'); const sauceSchema = mongoose.Schema({ userId: {type:String}, name: {type:String, required:true}, manufacturer:{type:String, required:true}, description:{type:String, required:true}, mainPepper: {type:String, required:true}, imageUrl:{type:String, required:true}, heat: {type:Number, required:true}, likes: {type:Number}, dislikes : {type:Number}, usersLiked : {type:["String <userId>"]}, usersDisliked: {type:["String <userId>"]}, }); module.exports = mongoose.model('sauce', sauceSchema);这个问题与this one 相呼应,但那里提供的解决方案对我帮助不大(顺便说一句,同样的情况)
好了,感谢您阅读我的长篇文章,感谢您提供的任何帮助。
-
【问题讨论】:
-
在你的
likeSauce路由中,为什么请求没有向你发送正在修改 like 状态的酱汁?我不明白你怎么可能在不知道人们喜欢哪种酱汁的情况下做正确的事? -
为什么
req.body.usersLiked和req.body.usersDisliked来自请求?是否有一些中间件正在设置这些。他们当然不应该来自客户。你能准确地显示来自客户端的数据吗? -
这段代码看起来也可能容易受到竞争条件的影响,因为您在异步操作中将数据库中的一组数据保存在内存中(这使其他请求有机会运行并与您的意图发生冲突或覆盖您的意图。
-
嘿 @jfriend00,感谢你的 cmets,但我发现自己有点不安地回答你。首先,我们已经在一个特定的 sauce 页面上,所以路由只选择 sauce 的 id。第二点,他们给了我们要插入模型的数组,但我认为没有中间件来设置它们。你问客户发送什么?好吧,console.log(req.body) 返回一个带有 userId 和 1 或 0 或 -1 的对象。第三点:有趣我会检查一下。
-
阵列从何而来?您显示它来自
req.body,这通常意味着它来自客户端。如果是这样,那真是一个糟糕的设计。客户端永远不应该管理阵列。客户端应该向您发送它想要对数组进行的单个修改,然后您通过将它们的增量修改与数据库中的当前数据合并来相应地更新数据库。
标签: javascript node.js mongodb