Question

I'm trying to model a many-to-many relationship in MongoDB with the added requirement that I keep track of "meta-data" on the relationship.

The models by themselves would look simple like this:

Student model
{ 
  _id: <ObjectID1>,
  name: "Foo Bar"
}

School model
{ _id: <ObjectID123>,
  name: "Cityville Highschool",
  location: "Cityville, Stateville"
}

Now, I want to link these in a many-to-many relationship so Students can be part of multiple Schools, and Schools can have many Students. Normally in MongoDB you could just keep an array of the other model in each model. For example:

Student model
{ 
  _id: <ObjectID1>,
  name: "Foo Bar",
  schools: [<SchoolID1>, <SchoolID2>, ...]
}

School model
{ _id: <ObjectID123>,
  name: "Cityville Highschool",
  location: "Cityville, Stateville",
  students: [<StudentID1>, <StudentID2>, ...]
}

But what if I now want to have data on that relationship? For example, a date on when the student entered and exited the school: "enter_date" and "exit_date". Normally, in sql, you would have a JOIN table for StudentSchool that looks like this:

StudentSchool:
{ studentId: 123,
  schoolId:  456,
  enter_date: 12-12-2014,
  exit_date:  12-12-2015
}

How would you do this in MongoDB? Some of the options I've ruled out already:

  1. Creating a new Collection (i.e. StudentSchool collection) that basically imitates the sql JOIN table. Ruled out because doesn't seem the right way to use Mongo, could also be difficult to manage for updates/deletes.
Was it helpful?

Solution

How about, in the Student model, you don't just put SchoolIds into the array, but entire documents providing the meta-data? E.g. enter_date, exit_date? Might be too much to have that annotation in both places (i.e. Student and School), but even that might be practicable, depending on the intended usage.

Student model
{ 
  _id: <ObjectID1>,
  name: "Foo Bar",
  schools: [
    { _id: <SchoolID1>,
      enter_date: ...,
      exit_date: ...
    },
    { _id: <SchoolID2>,
      enter_date: ...,
      exit_date: ...
    },
    ...
  ]
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top