【问题标题】:MongoDB: How to delete all comments of a deleted post?MongoDB:如何删除已删除帖子的所有评论?
【发布时间】:2017-07-03 10:18:16
【问题描述】:

我正在关注 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' });        
    });
});

不幸的是,当我删除这样的帖子时,任何相关的 cmets 都会留在数据库中的某个位置。所以,我的问题是如何在删除帖子的同时删除与帖子相关的所有 cmets?

我已尝试通过 Google 搜索答案,看来我应该以某种方式使用 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 工厂调用它。即使我这样做也不知道是否正确。因此,欢迎任何帮助。 :)

【问题讨论】:

  • 您甚至没有收到“已成功删除”的消息吗?您是否尝试过使用 Postman 对其进行测试?
  • @gh0st 我用路由器信息更新了我的问题。
  • @gh0st 我收到了消息,我可以毫无问题地删除帖子。问题是当我删除一个帖子时,所有相关的 cmets 都留在数据库中“浮动”。当相关帖子被删除时,我想摆脱它们。
  • 在您的Post.remove(); 调用Comments.remove(); 并传入与之关联的帖子的ID。
  • @gh0st 谢谢,就像一个魅力! :) 但我想知道这是否是删除引用的首选方法,而不是创建用于删除的自定义模式方法。有什么想法吗?

标签: angularjs mongodb mongoose mean-stack


【解决方案1】:

当您在 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。在某些情况下,实际删除文档是有意义的,但请记住这一点。

【讨论】:

  • 感谢您的建议,但它不起作用。如果我用它替换当前的 router.delete,我只会收到内部服务器错误 500。
  • 看来我根本无法使用 router.delete 访问 removePost 方法。该方法(removePost)当前与我的 PostSchema 位于同一文件中。这是它的正确位置吗?
  • 哦,好吧,如果你想在另一个文件中使用它,你必须导入这个函数。但是,您可以取而代之的是 removePost() 函数的胆量,然后从 delete 路由中调用它。
  • 我将如何(以及在​​何处)导入它?如果我同意你的建议,将removePost() 的内容包含在我的delete 路线中,我应该把PostSchema.pre 挂钩放在哪里?在我的PostSchema 所在的同一个文件中?
  • 是的,您可以将 pre 挂钩添加到与架构定义相同的文件中。查看节点docs 了解有关需要模块的信息
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2014-08-02
    • 2022-11-10
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    相关资源
    最近更新 更多