如何在 Mongo-DB 中删除多级引用模式

Posted

技术标签:

【中文标题】如何在 Mongo-DB 中删除多级引用模式【英文标题】:How to delete multi level referenced schemas in Mongo-DB 【发布时间】:2021-12-24 05:00:45 【问题描述】:

我正在创建一个 ERP 系统,其中学校有课程,课程包含学生。我想使用 API 删除学校,该学校也删除课程和所有注册课程的学生。

这就是我在 API 逻辑中所做的:-

app.delete("/fetchSchool/:schoolId", async (req, res) => 
try 
    const deletedSchool = await schools.findByIdAndDelete(req.params.schoolId);
    (!deletedSchool) ? res.send('Invalid Request'):
    courses.remove(_id: $in: deletedSchool.course, (error, deletedCourse) => 
        error ? res.send('Subsequent Deletion Of Course Failed'):
        students.remove(_id: $in: deletedCourse.students, (error, response) => 
            error ? res.send(error): res.send('Deletion Successfull');
        )
    )

  catch (error) 
     res.status(500).send('some error occured,' + error.message);
 
)

但这只会删除学校和学校中的课程,但学生数据仍然存在。

这是我的架构:-

学校架构

 const SchoolSchema = mongoose.Schema(
 course: [
     type: mongoose.Schema.Types.ObjectId,
     ref: 'course'
  ] 
 )

课程架构

const CourseSchema = mongoose.Schema(
students: [
    type: mongoose.Schema.Types.ObjectId,
    ref: 'student'
 ]
)

学生架构

const StudentSchema = mongoose.Schema(
name: 
    type: String,
    required: true
,
email: 
    type: String,
    unique: true
)

请告诉我删除学生以及学校和课程的正确方法。

【问题讨论】:

您是否考虑过使用关系数据库管理系统? 我正在将其作为我正在进行的实习中的一个项目来构建,他们要求我仅将 Mongo_Db 用于数据库目的 我认为remove 只返回删除的文档数,而不是文档本身。 @Joe 是的,你说得对,现在我想不出任何方法可以轻松做到这一点。 也许在运行remove 之前,使用相同的过滤器执行find,并投影以仅返回students 数组。当然,假设数组适合 16MB 的文档,那么展平应该可以提供最终删除所需的内容。 【参考方案1】:

首先,我会尝试找到学校。这是我最不想删除的内容,因为我们需要其中的 ID 和信息。

const school = await schools.findOne( _id: req.parmas.schoolId )

既然我已经获得了学校的信息,我将继续尝试删除课程。由于学生存储在一个数组中,因此我将不理会这些,只专注于删除课程。

Course.remove( 'students.type': school._id ).

删除课程后,您应该删除学校。

school.remove()

【讨论】:

【参考方案2】:

解决方案 #1

    找到学校。

    使用 school.courses 查找课程。

    通过课程映射。

    deleteMany students with course.students。

    删除课程。

    删除学校。

    app.get("/fetchSchool/:schoolId", async (req, res) => 
     const schoolId = req.params.schoolId;
    
     try 
         // find one school
         const findSchool = await schools.findOne( _id: schoolId );
    
         if (findSchool) 
             // find the courses in the school.courses
             const findCourses = await courses.find( _id:  $in: findSchool.courses  );
    
             if (findCourses) 
                 // map through courses to get every course
                 findCourses.map(async (course) => 
                     // find the students in the mapped course AND remove them
                     const deleteStudents = await students.deleteMany( _id:  $in: course.students  )
    
                     if (deleteStudents) 
                         // Remove the courses
                         const deletedCourses = await courses.deleteMany( _id:  $in: findSchool.courses  );
    
                         if (deletedCourses) 
                             // Remove the school
                             const deletedSchool = await schools.deleteOne( _id: schoolId );
    
                             if (deletedSchool) 
                                 res.status(200).send('Deleted (school, courses, students) successfully');
                              else  res.send("school not deleted") 
    
                          else  res.send("courses not deleted") 
    
                      else  res.send("courses not deleted") 
                 )
    
              else  res.send("no courses") 
    
          else  res.send("no school") 
    
      catch (error) 
         res.status(500).send('some error occured, ' + error.message);
     
    )
    

解决方案 #2

您可以在 Mongoose 中使用 PrePost 钩子,但请确保将其写在模型文件中的 mongoose.model() 行之前。

【讨论】:

以上是关于如何在 Mongo-DB 中删除多级引用模式的主要内容,如果未能解决你的问题,请参考以下文章

在linux如何批量删除多级目录下同一格式的文件呢?

如何在 Laravel Eloquent 中构建具有多级关系的查询

如何删除熊猫数据透视表中的多级索引

如何在 Spring Boot 中使用 Hibernate/JPA 返回多级 json

如何在org-mode中创建多级有序(编号)普通列表?

JavaScript中的多级引用?