【问题标题】:How should the following many to many relationship be modeled in MongoDB?MongoDB中应该如何建模以下多对多关系?
【发布时间】:2017-07-08 15:21:05
【问题描述】:
假设我有学生和老师的多对多关系。如果我只想找出给定学生的所有老师,反之亦然,我通常使用嵌入式对象 ID 对其进行建模。例如,如果教师有一个属性 studentIds,它是一个学生对象 ID 数组,那么这足以完成您需要的所有查询。
但是假设学生可以给老师打分。这个评级应该如何适应模型?目前我执行以下操作:
- 在教师内部而不是存储学生数组,我存储了一个
json 对象数组 {studentId: ObjectId, rating: String}
- 查询时,我将json对象数组转换为数组
的 studentIds 并像往常一样提取完整信息
- 所以现在我有一个学生对象数组和一个 json 对象数组
收视率
- 但是,由于 MongoDB 中的 $in 运算符不保留排序,我需要自己进行排序
- 在最后一步,一切都井井有条,我可以将学生对象与评级结合起来
得到我想要的
它有效,但似乎有点令人费解。有没有更好的方法来做到这一点?
【问题讨论】:
标签:
mongodb
many-to-many
modeling
nosql
【解决方案1】:
这里有一些注意事项。最后,这取决于您的要求:
-
评分是可选的,对吧?
如果是这样,请问问自己是否要将所需的功能(存储教师/学生关联)与一个不错的功能结合起来。实现一个不错的功能的代码现在写入您最重要的集合。我认为您可以使用不同的数据库架构改进代码中的关注点分离。
-
您是否需要更多功能?
假设您想向学生提供他们给出的评分列表、学生对教师的平均评分,并且您想显示评分随时间的变化。这对于嵌入的文档会非常混乱。 嵌入式文档不太灵活。
-
如果您需要顶级读取性能,则需要对更多数据进行非规范化
如果您想坚持嵌入的文档,您可能需要复制更多数据。假设有一个每位教师的评分概览,您可以在其中看到学生的姓名。嵌入对象会很有帮助
{ studentId : ObjectId,
rating: string,
studentName: string,
created: dateTime }
作为替代方案,请考虑
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 查询,反之亦然。这又是一个查询,但它带来了极大的灵活性。