在 updateOne mongoose 方法中更新现有或使用 mongo 运算符的功能
Posted
技术标签:
【中文标题】在 updateOne mongoose 方法中更新现有或使用 mongo 运算符的功能【英文标题】:Update in function of existing or using mongo operator in updateOne mongoose method 【发布时间】:2021-07-19 20:04:12 【问题描述】:情况:
我有一个赞按钮,我希望当用户点击数据库中的赞时:
如果用户还不喜欢它,则增加(如 +1 并从 likeBy 数组添加用户 ID)
如果用户已经喜欢它,则减少(如 - 1 并从 likeBy 数组中删除使用的 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: Cast to Number failed for value " '$cond': [ '$in': [Array] , '$inc': [Object] , '$inc': [Object] ] " 在路径 "like" [...] messageFormat: undefined, stringValue: '" '$cond': [ '$in': [数组] , '$inc': [Object] , '$inc': [对象] ] "', kind: 'Number', value: ..., path: 'like', ...
【问题讨论】:
你不需要额外的+
- $inc: like: +1
你可以使用 $inc: like: 1
【参考方案1】:
常规更新查询不允许使用内部字段和聚合运算符,如$cond
,因此不能使用常规更新查询进行此操作,
您可以从 MongoDB 4.2 开始尝试使用 update with aggregation pipeline,
您可以在聚合更新中使用$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 )
);
;
Playground
【讨论】:
我从您的代码中更改了javascript [ $in: [userId, "$likedBy"] , $add: ["$like", -1] , $add: ["$like", 1] ]
,它就像一个魅力:) 谢谢你以上是关于在 updateOne mongoose 方法中更新现有或使用 mongo 运算符的功能的主要内容,如果未能解决你的问题,请参考以下文章
updateOne $ set not working - Mongoose
TypeScript 中的 Mongoose post hook 类型错误
UpdateOne MongoDB 使用来自另一个字段的值进行推送
Mongoose 报错代码 (node:10256)(node:13604)(node:13604) DeprecationWarning: Mongoose: findOneAndUpdate()