MongoDB - 如何正确建模关系

时间:2017-09-27 06:54:19

标签: mongodb

假设我们有以下集合:

Users
{
  "id": MongoId,
  "username": "jsloth",
  "first_name": "John",
  "last_name": "Sloth",
  "display_name": "John Sloth"
}

Places
{
  "id": MongoId,
  "name": "Conference Room",
  "description": "Some longer description of this place"
}

Meetings
{
  "id": MongoId,
  "name": "Very important meeting",
  "place": <?>,
  "timestamp": "1506493396",
  "created_by": <?>
}

稍后,我们想要返回(例如来自REST webservice)即将发生的事件列表:

[
   {
      "id": MongoId(Meetings),
      "name": "Very important meeting",
      "created_by": {
         "id": MongoId(Users),
         "display_name": "John Sloth",
      },
      "place": {
         "id": MongoId(Places),
         "name": "Conference Room",
      }
   },
   ...
]

返回需要在web ui主页上显示的基本信息非常重要(因此不需要额外调用来呈现表格)。这就是为什么每个条目都包含创建它的用户的display_name和该地点的name。我认为这是一种非常常见的情况。

现在我的问题是:我应该如何在db(Metting文档中的问号值)中存储这些信息?我看到两个选项:

1)存储对其他馆藏的引用:

place: MongoId(Places)

(+)数据始终一致

( - )必须进行额外的db调用才能构建响应

2)非规范化数据:

  "place": {
     "id": MongoId(Places),
     "name": "Conference room",
  }

(+)不需要额外的调用(可以根据一个文档构建响应)

每次修改相关文档时都必须更新

( - )数据

处理这种情况的正确方法是什么?

如果我使用选项1),我该如何查询其他文件?分别询问每个相关文件似乎有点矫枉过正。如何获得最近20次会议,汇总相关文档列表,然后执行db.users.find({_id: { $in: <id list> }})

之类的查询

如果我选择选项2),我应该如何保持数据同步?

提前感谢任何建议!

1 个答案:

答案 0 :(得分:0)

您可以保留已有的数据库模型,但仍然只进行一次查询,因为MongoDB在3.2版中引入了$lookup aggregation。它类似于加入RDBMS。

  

$查找

     

对同一数据库中的未整数集合执行左外连接,以过滤“已连接”集合中的文档以进行处理。 $ lookup阶段在输入文档中的字段与“已连接”集合的文档中的字段之间进行相等匹配。

因此,不要存储对其他集合的引用,只需存储文档ID。