如何在MongoDB中建模以下多对多关系?

时间:2012-06-06 22:53:34

标签: mongodb many-to-many modeling nosql

假设我有多对多的学生和老师。如果我只是想找出给定学生的所有教师,反之亦然,我通常使用嵌入式对象ID对其进行建模。例如,如果教师有一个属性studentIds,它是一个学生对象ID数组,那么这就足以完成所需的所有查询。

但是假设学生可以给老师一个评级。该评级应该如何适应模型?目前我做了以下事情:

  1. 在老师的内​​心而不是存储一系列学生,我存储了一个 json对象数组{studentId:ObjectId,rating:String}
  2. 在进行查询时,我将json对象数组转换为数组 of studentIds并像往常一样提取全部信息
  3. 所以现在我有一个学生对象数组和一个json对象数组 评级
  4. 但是,由于MongoDB中的$ in运算符不保留排序,我需要自己进行排序
  5. 在最后一步,按顺序排列所有内容,我可以将学生对象与评分相结合 得到我想要的东西
  6. 它有效,但似乎有点复杂有没有更好的方法来做到这一点?

1 个答案:

答案 0 :(得分:1)

以下是一些注意事项。最后,这取决于您的要求:

  1. 评级是可选的,对吧?

    如果是这样,请问自己是否要将所需的功能(存储教师/学生协会)与可爱的功能相结合。实现一个很好的功能的代码现在写入您最重要的集合。我认为您可以使用不同的数据库架构改进代码中的关注点分离

  2. 您需要更多功能吗?

    假设您希望为学生提供他们给出的评分列表,学生给予教师的平均评分,以及您希望随着时间的推移显示评分的发展。嵌入式文档会非常混乱。 嵌入式文档不太灵活

  3. 如果您需要最佳读取性能,则需要对更多数据进行非规范化

    如果您想坚持使用嵌入式文档,则可能需要复制更多数据。让我们说每个教师的评分概述,你可以看到学生的名字。嵌入对象

    会很有帮助
    { studentId : ObjectId, 
      rating: string, 
      studentName: string, 
      created: dateTime }
    
  4. 作为替代方案,请考虑

    TeacherRating {
        StudentId: id
        TeacherId: id
        Rating: number
        Created: DateTime
    }
    

    教师/学生协会仍将存储在教师对象中,但评分属于不同的集合。如果找不到教师和学生之间的关联,则无法创建评级。

    TeacherStudentClass {
        StudentId: id
        TeacherId: id
        Class: id
        ClassName: string // (denormalized, just an example)
        Rating: number // (optional)
        Created: DateTime
    }
    

    要查找给定教师的所有学生,您必须先查询链接器文档,然后对学生进行$in查询,反之亦然。这是另一个问题,但它带来了巨大的灵活性。