删除一对一和一对多引用 - Mongoose

Sha*_*ane 12 javascript mongoose mongodb node.js

我有一个Assignment schema引用GroupsProjects.

Assignment == Group [One-One Relationship]
Assignment == Projects [One-Many Relationship]
Run Code Online (Sandbox Code Playgroud)

以下是我的Asssignment架构

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

如果Group/Project删除了a,我该如何更新我的Assignment Schema.

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

var GroupSchema = new Schema({
    name: String
});
Run Code Online (Sandbox Code Playgroud)

从stackoverflow中的几个答案,我开始了解删除中间件,但我不知道如何实现它的one-one and one-many关系.谁能告诉我一个这样做的例子.

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

    );
});
Run Code Online (Sandbox Code Playgroud)

Tha*_*var 15

关系:

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

one-one relationship - 如果a Project/Group被删除,我该如何更新我的AssignmentSchema.

通常,您将有一个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);                                      
                    }
                  });
            });
        });
}
Run Code Online (Sandbox Code Playgroud)

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

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

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);                                      
                    }
                  });
            });
        });
}
Run Code Online (Sandbox Code Playgroud)

删除中间件

你可以middleware通过约翰尼所指出的那样达到同样的目的,只是对此进行修正.

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

通常,可以有许多projects属于a assignment和许多assignments属于同一个project.您assignmentProjectSchema 中将有一个列,其中一个项目将与多个分配相关.

注意:删除中间件不适用于模型,它只适用于您的文档.如果你要使用remove中间件确保你的删除功能,你先找到projectid然后再返回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);
             } 
           });                
    });
 }
Run Code Online (Sandbox Code Playgroud)


Joh*_*yHK 6

remove 中间件中,您定义了通过删除该模式的模型文档时要采取的操作Model#remove.所以:

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

你可以实现如下:

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);
});
Run Code Online (Sandbox Code Playgroud)