MongoDB:如何删除已删除帖子的所有评论?

时间:2017-02-14 22:58:21

标签: angularjs mongodb mongoose mean-stack

我正在关注Thinkster的MEAN堆栈教程(https://thinkster.io/tutorials/mean-stack),它没有告诉我们应该如何实现删除操作。

我目前有以下架构:

var PostSchema = new mongoose.Schema({
  title: {type: String, required: true, maxlength: 140},
  link: {type: String, required: true, maxlength: 300},
  comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});

var CommentSchema = new mongoose.Schema({
  body: {type: String, maxlength: 200, minlength: 1},
  post: { type: mongoose.Schema.Types.ObjectId, ref: 'Post' }
});

我有一个用于CRUD操作的Angular工厂。我目前使用以下工厂方法删除帖子:

o.deletePost = function(id) {
  return $http.delete('/posts/' + id, null, {}
  }).success(function(res){
    $window.location.href = '/#/home'; 
    return res.data;
  });
};

我的删除路由器如下所示:

// DELETE a post
router.delete('/posts/:post', function(req, res, next) {  
    Post.remove({_id: req.params.post}, function(err, post) {
        if (err)
            res.send(err);

        res.json({ message: 'Successfully deleted' });        
    });
});

不幸的是,当我删除这样的帖子时,任何相关的评论都会留在数据库的某个地方。所以,我的问题是如何在删除该帖子时删除与帖子相关的所有评论?

我已经尝试过谷歌的答案,似乎我应该以某种方式使用MongoDB的中间件。我试过了:

// Remove Post
module.exports.removePost = function(id, callback){   
    Post.findById(id, function (err, doc) {
        if (err) {}

        doc.remove(callback);
    })
}

//Remove comments related to post
PostSchema.pre('remove', function(next) {

    this.model('Comment').remove({ post: this._id }, next);
});

但这并没有做任何事情,因为我不知道如何从我的CRUD工厂打电话。即使我这样做,也不知道它是否正确。所以,欢迎任何帮助。 :)

2 个答案:

答案 0 :(得分:0)

当您在Mongoose文档上调用remove()时,将自动触发Mongoose中间件。上面delete路由中的代码不会触发中间件,因为它在模型上调用remove()而不是文档(关于此here的对话)。

我认为你拥有所有的部分,你只需要移动它们。保留removePost()函数和pre('remove')中间件的逻辑,并将逻辑合并到删除路由中:

// DELETE a post
router.delete('/posts/:post', function(req, res, next) {
    Post.findById(id, function (err, post) {
        if (err) res.send(err);
        post.remove(function (err, doc) {
            if (err) res.send(err);
            res.json({ message: 'Successfully deleted' });
        });
    })
});

我接近"删除"尽管如此。我没有实际删除文档,而是在我的模式中添加deleted字段,并在删除时将该字段更新为true。在某些情况下,实际删除文档是有意义的,但这是需要牢记的。

答案 1 :(得分:0)

如果有人想知道究竟是什么解决了我的问题,这里有两个不同的解决方案:

第一个有效的,由gh0st建议,正在改变我的路由器以进行删除,如下所示:

// DELETE a post
router.delete('/posts/:post', function(req, res, next) {  
    Post.remove({_id: req.params.post}, function(err, post) {
        if (err) {res.send(err);}

        Comment.remove({post: req.params.post}, function(err, post) {
        if (err) {res.send(err);}                
        }); 

        res.json({ message: 'Successfully deleted' });        
    });    
});

第二个也有效,由holla建议,正在改变我的路由器以进行删除,如下所示:

// DELETE a post
router.delete('/posts/:post', function(req, res, next) {

    Post.findOne({ _id: req.params.post}, function (err, post) {
      if (err) {res.send(err);}

      post.remove(function (err) {
        if (err) {res.send(err);}

        res.json({ message: 'Successfully deleted' });
      });
    });
});

然后在我的架构文件中添加一个预钩子:

// Remove comments related to a post
PostSchema.pre('remove', function(next) {
    this.model('Comment').remove({ post: this._id }, next);
});