findOneAndRemove和findOneAndUpdate不能按预期工作

时间:2015-05-23 20:42:39

标签: javascript node.js mongodb express mongoose

我正在尝试制作一个"喜欢"像Facebook一样切换。

如果之前没有"喜欢"我的代码工作正常。

并在只有一个"喜欢"。

时删除查找

但是当有很多喜欢时它会开始成为问题。

因为我喜欢不同的帖子,

enter image description here

它增加了正确的参考

enter image description here

我又添了一个

enter image description here

现在这是问题 - 我实际按下了第三个切换按钮,但结果却不同了。最上面的一个被删除了。

我的Mongoose Schemas模型如下:

var postSchema  = new Schema({
    title: {type:String},
    content: {type:String},
    likeId:[{type:Schema.ObjectId, ref:'Like'}],
    user:{type:Schema.ObjectId},
    commentId:[{type:Schema.ObjectId, ref:'Comment'}],
    created:{type:Date, default:Date.now}
});

var likeSchema  = new Schema({
    user: Schema.ObjectId,
    postId: {type:Schema.ObjectId, ref:'Post'},
    created:{type:Date, default:Date.now}
});

没有中间件。

这是我的应用程序的控制器部分:

exports.postLikes = function(req,res){
    var like = new Like({
        postId: req.params.postId,
        user: req.user._id
    });
    Like.find()
    // find like "to the post" and "by the user"
    .and([
        {user:req.user._id},
        {postId:req.params.postId}
    ]) 
    //and then execute the following
    .exec(function(err, result){
        //if it exists, return "result"
        if(result.length > 0){ 
            //remove the result by result.id
            Like.findOneAndRemove(result[0]._id, function(err){ 
                //pull off the reference from likeId array in Post
                Post.findOneAndUpdate({'_id':req.params.postId}, {$pull:{'likeId':result[0]._id}}, function(err){ 
                    if(err){res.send(err);} 
                    res.json({status:'deleted'});
                });
            });
        }
        else{
            like.save(function(err){
                if(err){res.send(err);}
                Post.findById(req.params.postId, function(err,post){
                    if(err) return res.send(err);
                    post.likeId.push(like);
                    post.save(function(err){
                        if(err) return res.send(err);
                        res.json({status:'done'});
                    });
                });
            });         
        };
    });
};

请原谅我凌乱的代码。

我一直试图让它连续工作两天,无法找到方法。帮助我:(

我使用的数据是:

" LIKE" JSON OBJECT ARRAY

(喜欢的数据已被删除,所以我再次制作了它们)

/* 0 */
{
  "_id" : ObjectId("5560de9f9c93fb28161a7375"),
  "postId" : ObjectId("5560d511cae220180c37f9d3"),
  "user" : ObjectId("5560daf3a09140800bb70a41"),
  "created" : ISODate("2015-05-23T20:10:07.002Z"),
  "__v" : 0
}

/* 1 */
{
  "_id" : ObjectId("5560e7c98d6e3fbc15999daa"),
  "postId" : ObjectId("5560d514cae220180c37f9d4"),
  "user" : ObjectId("5560daf3a09140800bb70a41"),
  "created" : ISODate("2015-05-23T20:49:13.867Z"),
  "__v" : 0
}

/* 2 */
{
  "_id" : ObjectId("5560e7d78d6e3fbc15999dab"),
  "postId" : ObjectId("5560d515cae220180c37f9d5"),
  "user" : ObjectId("5560daf3a09140800bb70a41"),
  "created" : ISODate("2015-05-23T20:49:27.65Z"),
  "__v" : 0
}

" POST" JSON OBJECT ARRAY

/* 0 */
{
  "_id" : ObjectId("5560d511cae220180c37f9d3"),
  "title" : "titleteset",
  "content" : "contentetest",
  "user" : ObjectId("555d71825b6be608081553f1"),
  "created" : ISODate("2015-05-23T19:29:21.732Z"),
  "commentId" : [],
  "likeId" : [ObjectId("5560d542cae220180c37f9dd"), ObjectId("5560d7799dbb4fe8114fa90c"), ObjectId("5560d8c1194d94f80aa4f230"), ObjectId("5560dba8a09140800bb70a47")],
  "__v" : 19
}

/* 1 */
{
  "_id" : ObjectId("5560d514cae220180c37f9d4"),
  "title" : "titleteset",
  "content" : "contentetest",
  "user" : ObjectId("555d71825b6be608081553f1"),
  "created" : ISODate("2015-05-23T19:29:24.027Z"),
  "commentId" : [],
  "likeId" : [ObjectId("5560d554cae220180c37f9de"), ObjectId("5560de899c93fb28161a7374"), ObjectId("5560e7c98d6e3fbc15999daa")],
  "__v" : 4
}

/* 2 */
{
  "_id" : ObjectId("5560d515cae220180c37f9d5"),
  "title" : "titleteset",
  "content" : "contentetest",
  "user" : ObjectId("555d71825b6be608081553f1"),
  "created" : ISODate("2015-05-23T19:29:25.761Z"),
  "commentId" : [],
  "likeId" : [ObjectId("5560db7ea09140800bb70a46"), ObjectId("5560e7d78d6e3fbc15999dab")],
  "__v" : 4
}

添加:

我重构了我的代码@Andrew Layers建议,

我找到了:

{ _id: 5560ef48a082c31c0a29062f,
  postId: 5560d511cae220180c37f9d3,
  user: 5560daf3a09140800bb70a41,
  __v: 0,
  created: Sun May 24 2015 06:21:12 GMT+0900 (Korea Standard Time) }
POST /api/posts/5560d511cae220180c37f9d3/likes 200 26.621 ms - 179
{ _id: 5560ef48a082c31c0a29062f,
  postId: 5560d511cae220180c37f9d3,
  user: 5560daf3a09140800bb70a41,
  __v: 0,
  created: Sun May 24 2015 06:21:12 GMT+0900 (Korea Standard Time) }
POST /api/posts/5560d511cae220180c37f9d3/likes 200 14.333 ms - 179
{ _id: 5560ef48a082c31c0a29062f,
  postId: 5560d511cae220180c37f9d3,
  user: 5560daf3a09140800bb70a41,
  __v: 0,
  created: Sun May 24 2015 06:21:12 GMT+0900 (Korea Standard Time) }
POST /api/posts/5560d511cae220180c37f9d3/likes 200 20.195 ms - 179

我得到完全相同的结果变量,但findOneAndRemove删除了结果变量未指定的其他项。

问题似乎来自删除和删除参考的逻辑,但仍然不知道原因。

2 个答案:

答案 0 :(得分:2)

我在查询findOneAndRemove时发现了问题,并且只在id中找到它。 捂脸

使用findByIdAndRemove只是解决了问题。

所以我的固定代码现在是:

exports.postLikes = function(req,res){
    var like = new Like({
        postId: req.params.postId,
        user: req.user._id
    });
    Like.findOne({
        user:req.user._id,
        postId:req.params.postId
    }).exec(function(err, result){
        //if it exists, return "result"
        if(result) { 
            console.log(result);
            //remove the result by result.id
            Like.findByIdAndRemove(result._id, function(err){ 
                //pull off the reference from likeId array in Post
                Post.findByIdAndUpdate(req.params.postId, {$pull:{'likeId':result._id}}, function(err){ 
                    if(err){res.send(err);} 
                    res.json({status:'deleted', result:result});
                });
            });
        }
        else{
            console.log(result);
            like.save(function(err){
                if(err){res.send(err);}
                Post.findById(req.params.postId, function(err,post){
                    if(err) return res.send(err);
                    post.likeId.push(like);
                    post.save(function(err, foo){
                        if(err) return res.send(err);
                        res.json({status:'done', result:foo});
                    });
                });
            });         
        };
    });
};

它工作得很漂亮,现在我可以睡觉了,谢谢大家的帮助,尤其是@Andrew Lavers提出了更好的代码。

答案 1 :(得分:1)

我的第一个猜测是你的Like.find查询返回多个文档,findOneAndRemove代码只是删除列表中的第一个而不是你想要的特定文件。

您可以通过记录result.length来测试这一点,看看是否是这种情况。

在任何情况下,都没有理由创建Like对象来运行查询。 and()也没有必要。相反,您可以像这样使用findOne

Like.findOne({
    user:req.user._id,
    postId:req.params.postId
}).exec(function(err, result){
    //if it exists, return "result"
    if(result) { 
        //remove the result by result.id
        Like.findOneAndRemove(result._id, function(err){ 
            //pull off the reference from likeId array in Post
            Post.findOneAndUpdate({'_id':req.params.postId}, {$pull:{'likeId':result._id}}, function(err){ 
                if(err){res.send(err);} 
                res.json({status:'deleted'});
            });
        });
    } else {
        //...        
    }
});

如果文档不存在,result将为null,您的其他区块将会执行。