MongoDB 根据条件更新子文档(数组)的特定项目?
MongoDB update a specific item of sub document (array) based on condition?
我有一个 PostSchema,它有一个名为 votedBy 的 属性 数组:[],这是下面的 votedBySchema.Like 类型:
var votedBySchema = new Schema({
voteType:{
type:Boolean,default:false
},
voter:{
type:Schema.Types.ObjectId
}
});
const PostSchema = new Schema({
_authorId:{
type:Schema.Types.ObjectId,
required:true
},
title:{
type:String,
required:true
},
body:{
type:String,
},
date:{
type:Date
},
hidden:{
type:Boolean,
default:false
},
popularity:{
type:Boolean
},
votedBy:[{
type:votedBySchema,
}]
});
现在我从 postman 向 url /post/:postId
发出补丁请求。这里我 运行 一个中间件检查用户请求是否有一个有效的 token.And 将 userObject 和 token 放在 req 对象上。
接下来,我希望如果用户是 post 的作者,那么他可以更改关于 post 的所有内容,但如果他不是作者,那么他只能更改受欢迎程度,即 upVote 或 downVote。
我的逻辑是每个投票人都必须在 votedBy 数组中注册。
喜欢:
votedBy:[
{voteType:true,voter:'abcd@gmail.com'}, //upvote
{voteType:false,voter:'pqrs@gmail.com'}//downvote
]
由于电子邮件是唯一的,因此必须只能根据 votedBy 中的电子邮件对唯一条目进行 upVote 或 downVote。
我的路由逻辑代码:
app.patch('/post/:postId',authenticate,(req,res)=>{
console.log("[server.js]=>request ${req.method} to ${req.url}")
let body = _.pick(req.body,["title","body","popularity","hidden"])
let user = req.user;
let userId = user._id;
let postId = req.params.postId;
Post.findById(postId).then((post)=>{
let oldPost = post;//No use in code
console.log(`Found post ${post}`);
let postAuthorId = post._authorId.toString();
if(postAuthorId == userId){
post.title = body.title || post.title;//new,old
post.body = body.body || post.body;
post.hidden = body.hidden ||post.hidden;
post.update(post,{new:true}).then((postUpdated)=>{
console.log("Post Updated");
res.send(postUpdated);
});
}
else{
let voter = user.email;
console.log("\n voter is \n",voter)
let voteType = body.popularity;
//below code needs to be changed
/* post.update(
{
$set:{
'votedBy.$.voteType':voteType,
'votedBy.$.voter':voter
}
},
{
new:true
}
).then((iDontKnow)=>{
console.log('I dont know',iDontKnow);
res.send(post);
})*///Update or push the votedBy array for voter
}
});
});
注意我想提供与fb/youtube相同的投票功能。
还建议是否有其他解决方法。
这样做的想法很好,但如果我实现了,这将保留 userId 用于映射而不是用户电子邮件。
最终你会从前端获得 post 这样你就可以从前端发送值,但这不是一个很好的方法。
post.findOneAndUpdate( { userId : 'id of user from session' }, { "votedBy.$. voteType" : "true/false"}, { upsert : true }, callback );
因此您需要先执行查找操作以获取特定用户的投票类型值,然后更新它
路由代码类似于
dbOperation.getPostData(request.body.postId, userId , (err,result)=>{
if(err){ //log the error}
else if(result!=undefined){
dbOperation.updatePost(request.body, (err,result)=>{
if(err){ //log the error}
else{
response.json({message:'update',code:200,success:true});
}
});
else{
response.json({message:'post not found',code:404,success:false});
}
});
我有一个 PostSchema,它有一个名为 votedBy 的 属性 数组:[],这是下面的 votedBySchema.Like 类型:
var votedBySchema = new Schema({
voteType:{
type:Boolean,default:false
},
voter:{
type:Schema.Types.ObjectId
}
});
const PostSchema = new Schema({
_authorId:{
type:Schema.Types.ObjectId,
required:true
},
title:{
type:String,
required:true
},
body:{
type:String,
},
date:{
type:Date
},
hidden:{
type:Boolean,
default:false
},
popularity:{
type:Boolean
},
votedBy:[{
type:votedBySchema,
}]
});
现在我从 postman 向 url /post/:postId
发出补丁请求。这里我 运行 一个中间件检查用户请求是否有一个有效的 token.And 将 userObject 和 token 放在 req 对象上。
接下来,我希望如果用户是 post 的作者,那么他可以更改关于 post 的所有内容,但如果他不是作者,那么他只能更改受欢迎程度,即 upVote 或 downVote。
我的逻辑是每个投票人都必须在 votedBy 数组中注册。 喜欢:
votedBy:[
{voteType:true,voter:'abcd@gmail.com'}, //upvote
{voteType:false,voter:'pqrs@gmail.com'}//downvote
]
由于电子邮件是唯一的,因此必须只能根据 votedBy 中的电子邮件对唯一条目进行 upVote 或 downVote。
我的路由逻辑代码:
app.patch('/post/:postId',authenticate,(req,res)=>{
console.log("[server.js]=>request ${req.method} to ${req.url}")
let body = _.pick(req.body,["title","body","popularity","hidden"])
let user = req.user;
let userId = user._id;
let postId = req.params.postId;
Post.findById(postId).then((post)=>{
let oldPost = post;//No use in code
console.log(`Found post ${post}`);
let postAuthorId = post._authorId.toString();
if(postAuthorId == userId){
post.title = body.title || post.title;//new,old
post.body = body.body || post.body;
post.hidden = body.hidden ||post.hidden;
post.update(post,{new:true}).then((postUpdated)=>{
console.log("Post Updated");
res.send(postUpdated);
});
}
else{
let voter = user.email;
console.log("\n voter is \n",voter)
let voteType = body.popularity;
//below code needs to be changed
/* post.update(
{
$set:{
'votedBy.$.voteType':voteType,
'votedBy.$.voter':voter
}
},
{
new:true
}
).then((iDontKnow)=>{
console.log('I dont know',iDontKnow);
res.send(post);
})*///Update or push the votedBy array for voter
}
});
});
注意我想提供与fb/youtube相同的投票功能。 还建议是否有其他解决方法。
这样做的想法很好,但如果我实现了,这将保留 userId 用于映射而不是用户电子邮件。
最终你会从前端获得 post 这样你就可以从前端发送值,但这不是一个很好的方法。
post.findOneAndUpdate( { userId : 'id of user from session' }, { "votedBy.$. voteType" : "true/false"}, { upsert : true }, callback );
因此您需要先执行查找操作以获取特定用户的投票类型值,然后更新它
路由代码类似于
dbOperation.getPostData(request.body.postId, userId , (err,result)=>{
if(err){ //log the error}
else if(result!=undefined){
dbOperation.updatePost(request.body, (err,result)=>{
if(err){ //log the error}
else{
response.json({message:'update',code:200,success:true});
}
});
else{
response.json({message:'post not found',code:404,success:false});
}
});