我有两个模式。一个是用户模式,另一个是项目模式。用户模式中保存了对项目模式的引用。
const UserSchema = new Schema({
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
projects: [
{
type: Schema.Types.ObjectId,
ref: 'Project'
}
]
});
项目架构:
const projectSchema = new Schema({
experience: [
{
company: String,
positionExperience: String,
descriptionExperience: String,
websiteExperience: String,
timeperiodExperience: Array,
}
],
education: [
{
school: String,
degree: String,
descriptionEducation: String,
websiteEducation: String,
timeperiodEducation: Array
},
],
}, {
collection: 'project'
});
当当前登录的用户保存一个项目时,它会通过以下代码推入用户模式中的项目数组中: user.projects.push(project);
我有一个删除路由可以让用户删除项目:
router.delete('/delete/:id', passport.authenticate('jwt', { session: false }), (req, res, next) => {
Project.findByIdAndRemove({ _id: req.params.id }, (err) => {
if (err) res.json(err)
else res.json('Succesfully removed')
});
})
然而,在数据库中,当前登录用户的集合中未删除项目ID。数据库日志如下:
"_id" : ObjectId("5d9474c2dccfb181dd8e9fde"),
"projects" : [
ObjectId("5d9474cddccfb181dd8e9fdf"),
ObjectId("5d94753e9b610a81f83937e9"),
ObjectId("5d947602f72f0f820f2974f0"),
ObjectId("5d947ae435d2e982535d9a53"),
],
"username" : "b",
"password" : "$2a$10$4T1TjmFYD/01wEdMbiSRMeKNVKegnkVBOGGHasP.qJjVbQzmgEZDO",
"email" : "b",
所有的项目都已经被删除,但是它们的ID仍然存在于用户记录中。我需要某种垃圾回收机制来将它们也删除。我看了一下级联删除。级联删除意味着如果父表中的记录被删除,则对应的子表中的记录将自动删除。在我的情况下,用户是父表,我不想删除用户,而是要删除与用户相关联的项目。我尝试过像这样的方法:
User.findOne({ username: req.user.username }, (err, user) => {
Project.remove({
"_id": {
$in: user.projects
}
}, function(err) {
if(err) return next(err);
user.deleteOne()
})
})
但这会删除整个用户...我该如何同时从项目集合和与已登录用户相关的项目中删除一个项目?
* ----- 编辑 ----- *
经过进一步的挖掘,感谢非常有用的答案,这就是我想出来的:
//delete route
router.delete('/delete/:id', passport.authenticate('jwt', { session: false }), (req, res, next) => {
User.findOneAndUpdate({ username: req.user.username }, {
$pull: {
'projects': req.params.id
}
}, function (err, model) {
if (!err) {
Project.findByIdAndRemove({ _id: req.params.id }, (err) => {
if (err) res.json(err)
else res.json('Succesfully removed')
});
}
else {
res.status(500).json(err)
}
});
})
deleteOne()
,而是使用update()
和$pull
,并从用户对象中删除 projectId。 - Mohammed Amir Ansari