删除Mongo文档及其所有引用?

时间:2015-11-17 19:00:00

标签: javascript mongodb reference mongoose

在较高的层面上,我希望从Mongo中删除文档及其引用的文档。请看下面的示例模式:

var studentSchema = mongoose.Schema({
  email: String,
  name: String,
  _class: { type: String, ref: 'Class' },
  books: [{ type: Schema.Types.ObjectId, ref: 'Book' }]
});
module.exports = mongoose.model('Student', studentSchema);


var classSchema = mongoose.Schema({
  gradeLevel: Number,
  students: [{ type: Schema.Types.ObjectId, ref: 'Student' }]
});
module.exports = mongoose.model('Class', classSchema);


var bookSchema = mongoose.Schema({
  author: String,
  subject: String,
  pages: Number
});
module.exports = mongoose.model('Book', bookSchema);

现在,我的问题有两个方面:
1.如果我想从我的数据库中删除()一个类文档和所有引用它的学生文档,那么最好的方法是什么? //currently looping through students with the given class id and individually removing, then finally removing the class document.
2.如果我想从db和所有学生及其书中删除()一个类文档,有没有办法通过mongo中的特殊删除语句来完成这个? //Currently finding all students, removing their books, then remove themselves, then remove their referenced class.


理想情况下,我想要一个声明,可以删除mongo文档,以及引用它的任何内容,以及子文档可能具有的任何子引用。 (e.g: Remove a Class and have mongo auto-remove all Students and their Books)这可能吗?

1 个答案:

答案 0 :(得分:1)

没有声明可以在mongoDb或mongoose中执行您想要的操作。如果跨越多个集合的此类操作对您的应用程序非常重要(" MongoDB中没有自动支持的连接和参照完整性,那么MongoDB不是最佳选择;")。您还可能需要对数据建模更多"类似mongo"实现你想要的。

如果您有反向引用,则可以比循环更有效地执行此操作。 model.find()函数返回一个查询对象,该对象具有.remove(cb)方法

mongooose.model('Student').find({_class: myClassToRemove._id}).remove(function(err) {});

对于您的图书,这不起作用,因为Book没有Student的引用。但是如果你不在不同的学生之间分享书籍,那么你应该将书籍存储在学生对象中,作为"嵌入式文件"而不是使用不同的模型和参考。然后,当您删除学生时,它们将自动删除。

如果您在多个学生之间共享一个图书实例,则在删除学生时无法自动删除该图书,因为您不知道其他学生是否使用相同的图书实例。