假设我们有以下集合:
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),我应该如何保持数据同步?
提前感谢任何建议!
答案 0 :(得分:0)
您可以保留已有的数据库模型,但仍然只进行一次查询,因为MongoDB在3.2版中引入了$lookup
aggregation。它类似于加入RDBMS。
$查找
对同一数据库中的未整数集合执行左外连接,以过滤“已连接”集合中的文档以进行处理。 $ lookup阶段在输入文档中的字段与“已连接”集合的文档中的字段之间进行相等匹配。
因此,不要存储对其他集合的引用,只需存储文档ID。