【问题标题】:Removing one-one and one-many references - Mongoose删除一对一和一对多引用 - Mongoose
【发布时间】:2015-12-16 22:00:36
【问题描述】:

我有一个Assignment schema,它引用了Groups 和Projects。

Assignment == Group [One-One Relationship]
Assignment == Projects [One-Many Relationship]

下面是我的Asssignment 架构

var AssignmentSchema = new Schema({
    name: String,
    group: {
        type: Schema.Types.ObjectId,
        ref: 'Group'
    },
    projects: [{type: mongoose.Schema.Types.ObjectId, ref: 'Project'}],
});

如果删除了Group/Project,我如何更新我的分配架构。

var ProjectSchema = new Schema({
    name: String
});

var GroupSchema = new Schema({
    name: String
});

从 stackoverflow 中的几个答案中,我了解了删除中间件,但我不确定如何为 one-one and one-many 关系实现它。谁能给我看一个这样做的例子。

ProjectSchema.pre('remove', function(next){
    this.model('Assignment').update(

    );
});

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    在removemiddleware 中,您定义了当通过Model#remove 删除该架构的模型文档时要执行的操作。所以:

    • 删除组后,您希望从所有作业文档中删除对该组的_id 的group 引用。
    • 删除项目后,您希望从所有分配文档中删除对该项目的 _id 的 projects 数组元素引用。

    你可以实现为:

    GroupSchema.pre('remove', function(next) {
        var group = this;
        group.model('Assignment').update(
            { group: group._id }, 
            { $unset: { group: 1 } }, 
            { multi: true },
            next);
    });
    
    ProjectSchema.pre('remove', function (next) {
        var project = this;
        project.model('Assignment').update(
            { projects: project._id }, 
            { $pull: { projects: project._id } }, 
            { multi: true }, 
            next);
    });
    

    【讨论】:

      【解决方案2】:

      关系:

      1. one-to-one is a relationship 使得一个状态只有一个 首府城市和首府城市只是一个州的首府
      2. 一个one-to-many is a relationship 这样一个母亲有很多 孩子,孩子只有一个妈妈
      3. many-to-many is a relationship 这样一本书可以由 几位作者或合著者,而一个作者可以写几个 书籍。

      一对一关系 - 如果删除了 Project/Group,我如何更新我的 Assignment 架构。

      通常情况下,您会将一个 project 映射到一个 assignment,并且类似地将一个 assignment 映射到一个 project。您可以在这里做的是删除一个项目,然后在分配模型中找到关联的project 并删除它们的引用。

      delete: function(req, res) {
         return Project.findById(req.params.id, function(err, project){
               return project.remove(function(err){
                   if(!err) {
                       Assignment.update({_id: project.assignment}}, 
                            {$pull: {projects: project._id}}, 
                                function (err, numberAffected) {
                                  console.log(numberAffected);
                            } else {
                              console.log(err);                                      
                          }
                        });
                  });
              });
      }
      

      一对多关系 - 如果删除了 Project/Group,我如何更新我的 Assignment 架构。

      在这种情况下,我们将删除一个项目,然后找到属于此 project 的所有 assignments 并从中删除其引用。这里的情况是,一个项目可以有很多任务。

      delete: function(req, res) {
         return Project.findById(req.params.id, function(err, project){
               return project.remove(function(err){
                   if(!err) {
                       Assignment.update({_id: {$in: project.assingments}}, 
                            {$pull: {project: project._id}}, 
                                 function (err, numberAffected) {
                                  console.log(numberAffected);
                            } else {
                              console.log(err);                                      
                          }
                        });
                  });
              });
      }
      

      移除中间件

      正如 Johnny 所指出的,您可以通过 middleware 实现相同的目标,只是对此进行更正..

      ProjectSchema.pre('remove', function (next) {
          var project = this;
          project.model('Assignment').update(
              { projects: {$in: project.assignments}}, 
              { $pull: { project: project._id } }, 
              { multi: true }, 
              next
           );
      });
      

      通常可以有许多 projects 属于一个 assignment 和许多 assignments 属于同一个 project。您的 Project 架构中将有一个 assignment 列,其中一个项目将涉及多个分配。

      注意:删除中间件不适用于模型,它仅适用于您的文档。如果您在删除函数中使用remove 中间件确保,您首先通过id 找到project,然后在返回的document 上应用remove 方法,因此上述工作...您的删除函数看起来像这样。

      delete: function(req, res) {
         return Project.findById(req.params.id, function(err, project){
               return project.remove(function(err){
                   if(!err) {
                        console.log(numberAffected);
                   } 
                 });                
          });
       }
      

      【讨论】:

        猜你喜欢
        • 2015-12-06
        • 2013-11-29
        • 2019-12-17
        • 2012-09-04
        • 1970-01-01
        • 2015-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多