我想在我的学生模型和我的编队模型之间定义一对多的关系:1个学生属于1个阵型,一个阵型可以由N个学生组成。
我的需求是:
所以我写道:
let student = new Schema({
firstName: {
type: String
},
lastName: {
type: String
},
formation : {
type: Schema.Types.ObjectId,
ref: 'Formation'
}
});
let formation = new Schema({
title: {
type: String
},
students: [{ type: Schema.Types.ObjectId, ref: 'Student' }]
}
当我在搜索与mongodb / mongoose的一对多关系的文档时,我很惊讶地发现,当我想创建一个学生文档(并将其添加到一个编队)时,我不能只设置其形成id的“形成”字段,并将其推送到编队文档“学生”字段
这是否意味着当我想用另一个阵型替换学生的形成时,我需要1 /更新其形成区域2 /从形成“学生”字段中移除自己的学生ID并将其重新添加到学生领域的新阵型?
这对我来说似乎有点多余。我错过了什么吗?
答案 0 :(得分:2)
在编队模型上使用students
既是不好的做法,又是多余的。潜在无限阵列是一种糟糕的设计,因为它们可能导致达到文档大小限制。关于冗余,在这种情况下你只有两个查询:
1)你的内存中有一个student
,你想找到它们的形成:
Formation.findOne({_id: student.formation},callback);
2)你的记忆中有formation
,想找到那个阵型中的所有学生:
Student.find({formation: formation._id}, callback);
这两者都不需要在构造架构上使用students
。
答案 1 :(得分:1)
实际上它是多余的,因为您定义模式的方式是多余的。学生阵容应该是阵型的属性,但不是相反的。子文档可以像普通集合一样进行搜索。如果您将架构更改为:
let student = new Schema({
firstName: {
type: String
},
lastName: {
type: String
}
});
let formation = new Schema({
title: {
type: String
},
students: [{ type: Schema.Types.ObjectId, ref: 'Student' }]
}
您应该能够通过相当短的命令来满足您的需求。假设编队和学生是你的收藏品名称:
1:培养学生并保存队形和学生证件。
var stud = new student({name: "Sally"}); //Assuming you modeled to student
stud.save(function (err, student) {
formations.findOne({}, function (err, form) { //Dont know how you find formations, I assume you know
form.students.push(stud._id);
form.save(callback);
}
});
2。检索具有给定ID的学生的形成:
formations.findOne({"students" : { $elemMatch: {_id: id}}}, function (err, doc) {})
即使搬学生也相对简单。
formNew.students.push (
formOld.students.pop(formOld.students.indexOf(formOld.students.findOne(
//elemMatch like above
)))
抱歉奇怪的格式化。