MongoDB是否根据条件更新子文档(数组)的特定项目?

时间:2018-07-15 13:32:40

标签: mongodb subdocument

我有一个PostSchema,它的属性数组名为表决dBy:[],其类型为表决dBySchema。如下所示:

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,

}]
});

现在,我从邮递员发出一个补丁请求,并发送到URL /post/:postId。在这里,我运行一个中间件,检查用户请求是否具有有效的令牌。并将userObject和令牌放在req对象上。

接下来,我希望如果用户是帖子的作者,那么他可以更改帖子的所有内容,但是如果他不是作者,则只能更改受欢迎程度,即upVote或downVote。

我的逻辑是,每个投票人都必须以votedBy数组进行注册。 像:

votedBy:[
    {voteType:true,voter:'abcd@gmail.com'}, //upvote
    {voteType:false,voter:'pqrs@gmail.com'}//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相同的投票功能。 还建议是否还有其他方法。

1 个答案:

答案 0 :(得分:0)

这样做的想法很好,但是如果我实现了,它将保留userId用于映射,而不是用户电子邮件。

最终,您将从前端获得该帖子,以便可以从前端发送值,但这并不是一个好的方法。

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});
             }
});