我确信MongoDB没有正式支持"加入".这是什么意思?
这是否意味着"我们无法将两个集合(表格)连接在一起."?
我想如果我们把_id
集合A 的值放到other_id
集合B中,我们可以简单地连接两个集合吗?
如果我的理解是正确的,MongoDB可以将两个表连接在一起,比如说,当我们运行查询时.这是通过http://www.mongodb.org/display/DOCS/Schema+Design中的"参考"完成的.
那么"加入"究竟意味着什么呢?
我很想知道答案,因为这对学习MongoDB架构设计至关重要.http://www.mongodb.org/display/DOCS/Schema+Design
它不是连接,因为只有在需要时才会评估关系.另一方面,连接(在SQL数据库中)将解析关系并将它们作为单个表返回(您将"将两个表连接成一个").
您可以在此处阅读有关DBRef的更多信息:http: //docs.mongodb.org/manual/applications/database-references/
解析引用有两种可能的解决方案.一个是手动完成,正如你几乎所描述的那样.只需将文档的_id保存在另一个文档的other_id中,然后编写自己的函数来解决关系.另一种解决方案是使用上面手册页中描述的DBRef,这将使MongoDB 按需解析客户端关系.您选择哪种解决方案并不重要,因为这两种方法都将解决客户端关系(请注意,SQL数据库会解析服务器端的连接).
从Mongo 3.2开始,这个问题的答案已不再正确.添加到聚合管道的新$ lookup运算符与左外连接基本相同:
https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe._S_lookup
来自文档:
{ $lookup: { from:, localField: , foreignField: , as:
数据库不进行连接 - 或者在文档之间自动"链接".但是你可以自己做客户端.如果你需要做2,那没关系,但如果你不得不做2000,客户/服务器周转的数量会使操作变慢.
在MongoDB中,一种常见的模式是嵌入.正常化时,事物会被分解成几部分.通常在mongo中,这些部分最终成为单个文档,因此无论如何都不需要加入.但是当需要一个时,一个人做客户端.
考虑经典的ORDER,ORDER-LINEITEM示例.一个订单和8个订单项相关的是9行; 在MongoDB中,我们通常只将其建模为单个BSON文档,该文档是包含嵌入行项目数组的订单.因此,在这种情况下,不会出现连接问题.但是,订单将有一个CUSTOMER,它可能是一个单独的集合 - 客户端可以从订单文档中读取cust_id,然后根据需要单独获取它.
在我认为的mongodb.org网站上有一些关于模式设计会谈的视频和幻灯片.
一种在mongoDB中加入查询,在一个集合中询问匹配的id,将id放入一个列表(idlist),并在$ in:idlist中查找使用其他(或相同)集合
u = db.friends.find({"friends": something }).toArray() idlist= [] u.forEach(function(myDoc) { idlist.push(myDoc.id ); } ) db.family.find({"id": {$in : idlist} } )
您链接到的第一个示例显示了MongoDB引用的行为方式与延迟加载非常类似,不像连接.这两个集合上都没有查询,而是查询一个,然后通过引用从另一个集合中查找项目.
mongoDB不是关系的事实导致一些人认为它没用.我认为在设计数据库之前你应该知道自己在做什么.如果您选择使用noSQL DB(如MongoDB),则最好实现架构.这将使您的集合 - 或多或少 - 类似于SQL数据库中的表.此外,避免非规范化(嵌入),除非出于效率原因需要.
如果您想设计自己的noSQL数据库,我建议您查看Firebase文档.如果您了解他们如何为其服务组织数据,您可以轻松地为您设计类似的模式.
正如其他人指出的那样,除了使用Meteor(一个Javascript框架)之外,你将不得不进行客户端连接,你可以使用这个包进行服务器端连接(我不知道其他框架可以让你做所以).但是,我建议你在决定采用这个选择之前阅读这篇文章.
编辑28.04.17: 最近Firebase发布了关于设计noSql数据库的优秀系列.他们还在其中一个剧集中强调了避免连接的原因以及如何通过非规范化数据库来解决这些问题.