情况:
我有一个点赞按钮,我希望当用户点击数据库中的类似按钮时:
-
如果用户还不喜欢,则递增(如+1,并从likedBy数组中添加用户id(
-
如果用户已经喜欢它,则减少(如-1,并从likedBy数组中删除使用过的id(
代码:
控制器:
exports.likeIdea = (req,res,next) => {
const userId = getUserId(req)
Ideas.updateOne({ _id: req.params.id}, {
$set: {
like: {
$cond: [ {$in: [userId, "$likedBy"]}, { $inc: { like: +1 } } , { $inc: { like: -1 } } ]
},
likedBy: {
$cond: [ {$in: [userId, "$likedBy"]}, { $pull: { likedBy: userId } } , { $push: { likedBy: userId } } ]
},
_id: req.params.id
}
})
.then(() => res.status(200).json({ message: 'Success'}))
.catch(error => {
res.status(400).json({ error })
});
};
模式
const ideaSchema = mongoose.Schema({
name: { type: String, required: true},
sumup: { type: String, required: true },
description: { type: String, required: true},
published: {type: Boolean, required: true},
like: {type: Number, required: true},
likedBy: {type: [String]},
author: {type: String, required: true},
dislike: {type: Number, required: true},
dislikedBy: {type: [String]},
imgUrl: {type: String, required: true}
});
错误:
CastError:值"的强制转换为数字失败;{"$cond":[{"$in":[Array]},{"$sinc":[Object]};在路径"像";[…]{messageFormat:未定义,字符串值:""{
"$cond":[{'$in':[Array]},{"$inc":[Object]}[Object]}]}"',kind:"Number",值:{…},路径:"like",…}
常规更新查询不允许使用内部字段和像$cond
这样的聚合运算符,因此您不能使用常规更新查询、来执行此操作
您可以尝试从MongoDB 4.2、开始使用聚合管道进行更新
- 您可以在聚合更新中使用
$add
运算符而不是$inc
- 您可以使用
$filter
来删除特定用户,而不是$pull
- 可以使用
$concatArrays
运算符而不是$push
exports.likeIdea = (req,res,next) => {
const userId = getUserId(req)
Ideas.updateOne({ _id: req.params.id},
[{
$set: {
like: {
$cond: [
{ $in: [userId, "$likedBy"] },
{ $add: ["$like", 1] },
{ $add: ["$like", -1] }
]
},
likedBy: {
$cond: [
{ $in: [userId, "$likedBy"] },
{
$filter: {
input: "$likedBy",
cond: { $ne: ["$$this", userId] }
}
},
{ $concatArrays: ["$likedBy", [userId]] }
]
}
}
}]
).then(() => res.status(200).json({ message: 'Success'}))
.catch(error => {
res.status(400).json({ error })
});
};
游乐场