one to many with mongoose one to many with mongoose mongoose mongoose

one to many with mongoose


Having students on the Formation model is both bad practice and redundant. Potentially infinite arrays are a poor design as they can lead to hitting document size limits. In regards to being redundant, you only have two queries in this situation:

1) You have a student in memory, and you want to find their formation:

Formation.findOne({_id: student.formation},callback);

2) You have a formation in memory, and want to find all students in that formation:

Student.find({formation: formation._id}, callback);

Neither of which require having students on the Formation schema.


It is in fact redundant because the way you have defined your schemas is redundant. The array of students should be a property of the formation, but not the other way around. Subdocuments can be searched like normal collections. If you change your schema to:

let student = new Schema({    firstName: {        type: String    },    lastName: {        type: String    }});let formation = new Schema({    title: {        type: String    },    students: [{ type: Schema.Types.ObjectId, ref: 'Student' }]}

You should be able to accomplish your needs with fairly short commands. Assuming formations and students are your collection names:

1: Generating a student and saving both the formation and student documents.

var stud = new student({name: "Sally"}); //Assuming you modeled to studentstud.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. Retrieving the formation of a student with a given ID:

formations.findOne({"students" : { $elemMatch: {_id: id}}}, function (err, doc) {})
  1. Even moving a student is relatively simple.

    formNew.students.push (

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

Sorry about the weird formatting.