猫鼬一对多
one to many with mongoose
我想在我的Student模型和我的Formation模型之间定义一个一对多的关系:1个学生属于1个编队,一个编队可以由N个学生组成。
我的需求是:
- 能够用学生填充 Formation 文档
- 轻松检索学生的队形
所以我写道:
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 的一对多关系的文档时,我很惊讶地发现,当我想创建一个学生文档(并将其添加到编队中)时,我不仅要把它的"formation"字段设置成formation id,还要把它push到formation document的"students"字段。
这是否意味着当我想用另一个编队替换一个学生的编队时,我需要 1/ 更新其编队字段 2/ 从编队 "students" 字段中删除自己的学生 ID 并重新添加它到新编队的学生场?
这对我来说似乎有点多余。我错过了什么吗?
在 Formation 模型上设置 students
既不好又多余。潜在的无限数组是一种糟糕的设计,因为它们会导致达到文档大小限制。关于冗余,在这种情况下你只有两个查询:
1) 你记忆中有一个student
,你想找到他们的阵型:
Formation.findOne({_id: student.formation},callback);
2) 你记忆中有一个formation
,想找出那个阵型的所有学生:
Student.find({formation: formation._id}, callback);
两者都不需要在 Formation 架构上有 students
。
它实际上是多余的,因为您定义模式的方式是多余的。学生的排列应该是属性的队形,但不是。可以像正常 collection 一样搜索子文档。如果您将架构更改为:
let student = new Schema({
firstName: {
type: String
},
lastName: {
type: String
}
});
let formation = new Schema({
title: {
type: String
},
students: [{ type: Schema.Types.ObjectId, ref: 'Student' }]
}
您应该能够使用相当短的命令来满足您的需求。假设编队和学生是你的 collection 名字:
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
)))
对于奇怪的格式感到抱歉。
我想在我的Student模型和我的Formation模型之间定义一个一对多的关系:1个学生属于1个编队,一个编队可以由N个学生组成。
我的需求是:
- 能够用学生填充 Formation 文档
- 轻松检索学生的队形
所以我写道:
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 的一对多关系的文档时,我很惊讶地发现,当我想创建一个学生文档(并将其添加到编队中)时,我不仅要把它的"formation"字段设置成formation id,还要把它push到formation document的"students"字段。
这是否意味着当我想用另一个编队替换一个学生的编队时,我需要 1/ 更新其编队字段 2/ 从编队 "students" 字段中删除自己的学生 ID 并重新添加它到新编队的学生场?
这对我来说似乎有点多余。我错过了什么吗?
在 Formation 模型上设置 students
既不好又多余。潜在的无限数组是一种糟糕的设计,因为它们会导致达到文档大小限制。关于冗余,在这种情况下你只有两个查询:
1) 你记忆中有一个student
,你想找到他们的阵型:
Formation.findOne({_id: student.formation},callback);
2) 你记忆中有一个formation
,想找出那个阵型的所有学生:
Student.find({formation: formation._id}, callback);
两者都不需要在 Formation 架构上有 students
。
它实际上是多余的,因为您定义模式的方式是多余的。学生的排列应该是属性的队形,但不是。可以像正常 collection 一样搜索子文档。如果您将架构更改为:
let student = new Schema({
firstName: {
type: String
},
lastName: {
type: String
}
});
let formation = new Schema({
title: {
type: String
},
students: [{ type: Schema.Types.ObjectId, ref: 'Student' }]
}
您应该能够使用相当短的命令来满足您的需求。假设编队和学生是你的 collection 名字:
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
)))
对于奇怪的格式感到抱歉。