【问题标题】:How to automatically destroy 1-M connections in MongoDB and Meteor如何在 MongoDB 和 Meteor 中自动销毁 1-M 连接
【发布时间】:2015-05-20 03:06:01
【问题描述】:

我目前正在构建一个竞赛应用程序,其中有竞赛集合、问题集合、条目集合和答案集合。我的问题是,当我删除比赛时,我不知道最好的方法是删除属于比赛的所有问题、答案和条目。这就是我目前处理问题的方式:

Template.ContestItem.events({
'click .delete': function(e, tmpl) {
    e.preventDefault();

    var currentContestId = this._id;

    var entries = Entries.find({contest_id: currentContestId});

    var questions = Questions.find({contest_id: currentContestId});

    var answers = Answers.find({contest_id: currentContestId});

    answers.forEach(function(answer) {
        Answers.remove(answer._id);
    });

    questions.forEach(function(question) {
        Questions.remove(question._id);
    });

    entries.forEach(function(entry) {
        Entries.remove(entry._id);
    });


    Contests.remove(currentContestId);
  }
});

我觉得必须有更好的方法来做到这一点......我的解决方案似乎被破解了。我对 MongoDB 不是很熟悉,所以这可能是一个明显的错误。请让我知道是否有更好的方法。谢谢!

这是我的仓库:https://github.com/ryanswapp/rymotion

【问题讨论】:

  • 为什么不直接删除收藏?
  • 很简单。如果您只是删除集合,那么您没有删除所有内容的开销。 .remove() 是有代价的。 .drop() 非常即时。
  • 那么我可以将特定文档放到集合中吗?我不想放弃整个收藏,因为还有其他竞赛,包括问题、条目和答案。我对 nosql 完全陌生,所以当我听到“drop”时,我会想到完全擦除关系数据库。
  • 对不起。大大的误读。你想要像“级联删除”这样的东西,不是吗?我相信有一个猫鼬插件。但当然它不是“事务性的”,因为这在 MongoDB 集合中是不可能的,除非代码库在客户端上考虑了所有因素。
  • 不用担心。是的,我在 Rails 模型中的 has_many 关系上寻找类似“dependent::destroy”的东西。也许 MongoDB 没有这样的东西?

标签: javascript mongodb meteor database


【解决方案1】:

我会使用 collection-hooks 包并删除 after.remove 挂钩上的所有项目:

https://github.com/matb33/meteor-collection-hooks#afterremoveuserid-doc

Template.ContestItem.events({ 'click .delete': function(e, tmpl) {
    e.preventDefault();
    Contests.remove(this._id);
});

在一些服务器代码中:

Contests.after.remove(function (userId, contest) {
   Entries.remove({ contest_id: contest._id });
   Questions.remove({ contest_id: contest._id });
   Answers.remove({ contest_id: contest._id });
});

【讨论】:

  • 那个包看起来很不错。我认为这就是我正在寻找的。我得试一试!
  • 很高兴您发现这很有帮助。它是大多数 Meteor 应用程序的必备包。
【解决方案2】:

如果你在服务器方法中使用它,那么你可以缩短你的代码:

Template.ContestItem.events({
    'click .delete': function(e, tmpl) {
        e.preventDefault();

        var currentContestId = this._id;

        Meteor.call("deleteContest",currentContestId);
    }
});

在服务器上:

Meteor.methods({
  deleteContest: function(currentContestId) {
    var entries = Entries.remove({contest_id: currentContestId});

    var questions = Questions.remove({contest_id: currentContestId});

    var answers = Answers.remove({contest_id: currentContestId});

    Contests.remove(currentContestId);
    }
});

虽然它不适用于客户端,但我认为你不想让客户端从数据库中删除东西。同样在服务器上也不是异步的,因此您可以安全地让它们链接起来。 除此之外,我看不出您可以如何改进(除了验证现有的比赛 ID 和删除或错误处理等数据)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 2016-07-08
    • 1970-01-01
    相关资源
    最近更新 更多