【发布时间】:2020-08-24 08:57:48
【问题描述】:
我正在尝试做简单的事情,从 mongo 数据库中带有 mongoose 的数组中提取 userId,并通过 findByIdAndUpdate 方法更新对象。在这里,我使用“$pull”“$addToSet”方法(如切换)从数组中添加和删除 userId。简而言之,我的目标是在点击时喜欢,而不是在第二次点击时喜欢。所以我把'$pull'和'$addToSet'放在三元表达式中,并在findByIdAndUpdate()方法中使用它,如下所示:
exports.getLikeCounts = async (req, res) => {
const likes = Review({_id: req.params.id}).likes.map(obj => obj.toString());
//ternarry expression
const likeOperator = likes.includes(req.user._id) ? '$pull' : '$addToSet';
const likeReview = await Review
.findByIdAndUpdate( {_id: req.params.id},
{[likeOperator]: {likes: req.user._id}},
{new: true}
)
res.json(likeReview);
}
在这里它只添加但不会在第二次单击时从数组中提取 userId。 我不明白缺少什么,任何帮助将不胜感激。
我的模型结构如下:
likes:[
{ type: mongoose.Schema.ObjectId, ref: 'User'}
]
注意:如果我像这样直接使用 pull 和 addtoset: {'$pull' 或 '$addToSet': {likes: req.user._id}} 进行测试,它可以工作,但在三元表达式中,就像我上面使用的那样两者都不起作用,但只有 addtoset。
【问题讨论】:
-
问题不在于三元表达式。您将喜欢的
_id转换为obj.toString()的String,当您将likes.includes与likes.includes进行比较时,您确定req.user._id也是String?我想他们都应该是ObjectId,你不需要任何转换。同样.findByIdAndUpdate()接受_id作为第一个参数,所以它应该是req.params.id而不是{ _id: req.params.id } -
include 方法在数组中搜索数据。 arr.include,但您正在传递对象。
-
感谢@Asif 和 TheeSritabtim 的回答。 Asif 数组中的数据都在字符串中,就像将 obj 更改为字符串一样。但即使我将 userId 更改为附加到它的字符串 user._id.toString() 或直接传递对象而不更改为字符串数组 obj 和 userId。在 .findByIdAndUpdate() 方法中,我使用了 req.params.id 但仍然没有任何变化。仍然堆叠在这上面。
-
我猜
req.user._id是ObjectId。在这种情况下,只需删除.map(obj => obj.toString()),它应该可以工作 -
感谢您的想法@TheeSritabtim,它为我提供了更多选项,效果相同,但仍然没有任何改变。根据您的想法,结果如下所示:exports.getLikeCounts = async (req, res) => { const likes = Review({_id: req.params.id}).likes;常量 likeOperator = likes.includes(req.user._id) ? '$pull' : '$addToSet'; const likeReview = await Review .findByIdAndUpdate(req.params.id, {[likeOperator]: {likes: req.user._id}}, {new: true} ) console.log('点赞的评论:', likeReview); res.json(likeReview); }
标签: javascript node.js mongodb mongoose ecmascript-6