简体   繁体   中英

how to deal with many-to-many relationship in mongodb?

it is easy to deal with 1-1(via refs) or 1-N(via populate virtuals) relations in MongoDB
but how to deal with NM relations?
suppose I have 2 entities teacher and classroom
many teachers can access many classrooms
many classrooms can be accessed by many teachers

teacher.schema
{
  name:String;
  //classrooms:Array;
}
classrooms.schema
{
  name:String;
  //teachers:Array
}

is there a direct way (similar like populate virtuals) to keep this NM relations so that when one teacher removed, then teachers in classroom can automatically be changed too?
should I use a third 'bridge' schema like TeacherToClassroom to record their relations?

i am thinking of some thing like this, like a computed value

teacher.schema
{
  name:String;
  classrooms:(row)=>{
    return db.classrooms.find({_id:{$elemMatch:row._id }})
  }
}
classrooms.schema
{
  name:String;
  teachers:{Type:ObjectId[]}
}

so that i just manage the teacher ids in classrooms, then the classroom property in teach schema will auto computed

The literature describes a few methods on how to implement a mn relationship in Mongodb.

The first method is by two-way embedding. Looking at an example using books and director of movies:

{
  _id: 1,
  name: "Peter Griffin",
  books: [1, 2]
}
{
  _id: 2,
  name: "Luke Skywalker",
  books: [2]
}

{
  _id: 1,
  title: "War of the oceans",
  categories: ["drama"],
  authors: [1, 2]
}
{
  _id: 2,
  title: "Into the loop",
  categories: ["scifi"],
  authors: [1]
}

The second option is to use one-way embedding. This means you only embed one of the documents into the other. Like so (movie with a genre):

{
  _id: 1,
  name: "drama"
}

{
  _id: 1,
  title: "War of the oceans",
  categories: [1],
  authors: [1, 2]
}

When the data you are embedding becomes larger you could use something like the bucketing pattern to split it up: https://www.mongodb.com/blog/post/building-with-patterns-the-bucket-pattern

As you can see in the above example by embedding the documents you still only need to modify the data in one location. You do not need any intermediate tables to do that.

In some cases you might even be able to omit an entire document when it has no meaning as a stand-alone object: Absorbing N in a M:N relationship

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM