Pet*_*son 27 mongoose mongodb node.js
我们假设我有这样的架构:
var Person = new Schema({
name: String
});
var Assignment = new Schema({
name: String,
person: ObjectID
});
Run Code Online (Sandbox Code Playgroud)
如果我删除一个人,仍然会有一些孤立的分配,引用一个不存在的人,这会在数据库中造成无关紧要的混乱.
是否有一种简单的方法可以确保在删除某个人时,对该人的所有相应引用也将被删除?
Joh*_*yHK 33
您可以在架构上添加自己的'remove'Mongoose 中间件,Person以从引用它的所有其他文档中删除该人员.在您的中间件功能中,this是Person要删除的文档.
Person.pre('remove', function(next) {
// Remove all the assignment docs that reference the removed person.
this.model('Assignment').remove({ person: this._id }, next);
});
Run Code Online (Sandbox Code Playgroud)
remove()方法已弃用。因此,在您的 Mongoose 中间件中使用“删除”可能不再是最佳实践。
Mongoose 已经创建了更新来为deleteMany()和提供钩子deleteOne()。你可以用那些代替。
Person.pre('deleteMany', function(next) {
var person = this;
person.model('Assignment').deleteOne({ person: person._id }, next);
});
Run Code Online (Sandbox Code Playgroud)
小智 6
即使引用的个人文档已被删除,您也可以保留文档不变。Mongodb 会清除指向不存在文档的引用,这不会在删除引用文档后立即发生。相反,当您对文档执行操作(例如更新)时。而且,即使在清除引用之前查询数据库,返回的也是空的,而不是空值。
第二个选项是使用$unset运算符,如下所示。
{ $unset: { person: "<person id>"} }
Run Code Online (Sandbox Code Playgroud)
请注意使用人员 ID 来表示查询中引用的值。
如果有人在寻找 pre hook 但 fordeleteOne和deleteManyfunctions,这是一个对我有用的解决方案:
const mongoose = require('mongoose');
...
const PersonSchema = new mongoose.Schema({
name: {type: String},
assignments: [{type: mongoose.Schema.Types.ObjectId, ref: 'Assignment'}]
});
mongoose.model('Person', PersonSchema);
....
const AssignmentSchema = new mongoose.Schema({
name: {type: String},
person: {type: mongoose.Schema.Types.ObjectId, ref: 'Person'}
});
mongoose.model('Assignment', AssignmentSchema)
...
PersonSchema.pre('deleteOne', function (next) {
const personId = this.getQuery()["_id"];
mongoose.model("Assignment").deleteMany({'person': personId}, function (err, result) {
if (err) {
console.log(`[error] ${err}`);
next(err);
} else {
console.log('success');
next();
}
});
});
Run Code Online (Sandbox Code Playgroud)
deleteOne在服务中的某处调用函数:
try {
const deleted = await Person.deleteOne({_id: id});
} catch(e) {
console.error(`[error] ${e}`);
throw Error('Error occurred while deleting Person');
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15683 次 |
| 最近记录: |