猫鼬一对多

one to many with mongoose

我想在我的Student模型和我的Formation模型之间定义一个一对多的关系: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 的一对多关系的文档时,我很惊讶地发现,当我想创建一个学生文档(并将其添加到编队中)时,我不仅要把它的"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) {})
  1. 连搬一个学生都比较简单。

    formNew.students.push (

formOld.students.pop(formOld.students.indexOf(formOld.students.findOne( //elemMatch like above )))

对于奇怪的格式感到抱歉。