如何在 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 中使用 Pre 和 Post 钩子,但请确保将其写在模型文件中的 mongoose.model() 行之前。
【讨论】:
以上是关于如何在 Mongo-DB 中删除多级引用模式的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Laravel Eloquent 中构建具有多级关系的查询