【问题标题】:how to deal with many-to-many relationship in mongodb?如何处理mongodb中的多对多关系?
【发布时间】:2019-12-04 15:12:00
【问题描述】:

在 MongoDB 中处理 1-1(通过 refs)或 1-N(通过填充虚拟)关系很容易
但是如何处理 N-M 关系呢?
假设我有 2 个实体老师和教室
许多教师可以访问许多教室
许多教师可以访问许多教室

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

是否有一种直接方式(类似于填充虚拟)来保持这种 N-M 关系,以便当一位老师被移除时,课堂上的老师也可以自动更换?
我应该使用像TeacherToClassroom 这样的第三个“桥”模式来记录他们的关系吗?

我在想这样的事情,比如computed value

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

所以我只管理教室中的教师 ID,然后教学模式中的教室属性将自动计算

【问题讨论】:

  • 我看到您编辑了大部分帖子。我的回答还能为您提供解决方案吗?
  • 谢谢,但对不起兄弟。你anwser中的信息是我已经知道的。但这无济于事。我评论了你并解释了我的想法和寻找的东西

标签: mongodb mongoose-populate auto-populate


【解决方案1】:

文献中描述了如何在 Mongodb 中实现 m-n 关系的几种方法。

第一种方法是双向嵌入。看一个使用书籍和电影导演的例子:

{
  _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]
}

第二种选择是使用单向嵌入。这意味着您只能将其中一个文档嵌入到另一个文档中。像这样(有流派的电影):

{
  _id: 1,
  name: "drama"
}

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

当您嵌入的数据变大时,您可以使用分桶模式之类的方法将其拆分:https://www.mongodb.com/blog/post/building-with-patterns-the-bucket-pattern

正如您在上面的示例中看到的,通过嵌入文档,您仍然只需要在一个位置修改数据。您不需要任何中间表来执行此操作。

在某些情况下,当整个文档作为独立对象没有意义时,您甚至可以省略它:Absorbing N in a M:N relationship

【讨论】:

  • 我关心 2 个实体的一致性,我希望当我更新一侧时,另一侧也会自动更新。所以我使用 refs 并填充 virtuals。后来我考虑了 M:N 关系,我卡住了
  • @KentWood 如果您查看我的示例中的代码,您会发现不需要更新关系的两侧,因为您应该嵌入的只是对另一个文档的引用(唯一标识符) .这意味着永远不会出现一致性问题。在我看来,您认为应该嵌入完整的文档,这是不正确的。它会不必要地重复信息。通过这样做,您也限制了自己,因为没有好的方法(必须以编程方式完成)来使双方的信息保持最新。
  • 不,我不想嵌入完整的文档。相反,我有使用 RDBMS 的经验,所以我更喜欢使用 refs 来链接实体,就像在 mysql 中添加外键一样。是的,我正在寻找可以在 Schema 中定义的“直接解决方案”,也许这不是这样的事情,也许我必须以编程方式实现这一目标
猜你喜欢
  • 2020-10-09
  • 2018-09-17
  • 2021-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 1970-01-01
相关资源
最近更新 更多