当前位置:  开发笔记 > 编程语言 > 正文

MongoDB和"加入"

如何解决《MongoDB和"加入"》经验,为你挑选了6个好方法。

我确信MongoDB没有正式支持"加入".这是什么意思?

这是否意味着"我们无法将两个集合(表格)连接在一起."?

我想如果我们把_id集合A 的值放到other_id集合B中,我们可以简单地连接两个集合吗?

如果我的理解是正确的,MongoDB可以将两个表连接在一起,比如说,当我们运行查询时.这是通过http://www.mongodb.org/display/DOCS/Schema+Design中的"参考"完成的.

那么"加入"究竟意味着什么呢?

我很想知道答案,因为这对学习MongoDB架构设计至关重要.http://www.mongodb.org/display/DOCS/Schema+Design



1> Emil Vikströ..:

它不是连接,因为只有在需要时才会评估关系.另一方面,连接(在SQL数据库中)将解析关系并将它们作为单个表返回(您将"将两个表连接成一个").

您可以在此处阅读有关DBRef的更多信息:http: //docs.mongodb.org/manual/applications/database-references/

解析引用有两种可能的解决方案.一个是手动完成,正如你几乎所描述的那样.只需将文档的_id保存在另一个文档的other_id中,然后编写自己的函数来解决关系.另一种解决方案是使用上面手册页中描述的DBRef,这将使MongoDB 按需解析客户端关系.您选择哪种解决方案并不重要,因为这两种方法都将解决客户端关系(请注意,SQL数据库会解析服务器端的连接).


@groovydotcom了解这一点你必须了解这两天和nosql的动机.Nosql针对大量读取和写入操作进行了优化.巨大的.客户端计算机和应用程序服务器比几年前更快.理论上是将昂贵的连接操作卸载到服务器和客户端机器的应用程序,以允许数据库服务器尽可能快地简化读取和写入操作.
那么这是一个正确的答案,它提出了为什么MongoDB不支持这个服务器端的问题?是否只是为了阻止它的使用并鼓励非规范化?非规范化有时对资源的效率太低.为什么在这种情况下强制客户端/服务器转向?
@scaryguy,"服务器端"将在MongoDB应用程序中,而"客户端"是您的应用程序代码.您的应用程序作为客户端连接到MongoDB服务器.不要把它与机器混淆; 两个进程可能在同一台机器上运行.客户端和服务器只是描述了进程间通信中的两个不同角色.

2> Clayton Guli..:

从Mongo 3.2开始,这个问题的答案已不再正确.添加到聚合管道的新$ lookup运算符与左外连接基本相同:

https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe._S_lookup

来自文档:

{
   $lookup:
     {
       from: ,
       localField: ,
       foreignField: ,
       as: 
     }
}


$ lookup的限制:1)$ lookup仅支持匹配的相等性,并且相等必须在每个集合的单个键之间.2)$ lookup的右集合无法分片

3> dm...:

数据库不进行连接 - 或者在文档之间自动"链接".但是你可以自己做客户端.如果你需要做2,那没关系,但如果你不得不做2000,客户/服务器周转的数量会使操作变慢.

在MongoDB中,一种常见的模式是嵌入.正常化时,事物会被分解成几部分.通常在mongo中,这些部分最终成为单个文档,因此无论如何都不需要加入.但是当需要一个时,一个人做客户端.

考虑经典的ORDER,ORDER-LINEITEM示例.一个订单和8个订单项相关的是9行; 在MongoDB中,我们通常只将其建模为单个BSON文档,该文档是包含嵌入行项目数组的订单.因此,在这种情况下,不会出现连接问题.但是,订单将有一个CUSTOMER,它可能是一个单独的集合 - 客户端可以从订单文档中读取cust_id,然后根据需要单独获取它.

在我认为的mongodb.org网站上有一些关于模式设计会谈的视频和幻灯片.


@VijaySali你搜索它... db.collection.find({"orders.lineitems.SKU":"ABC001"}); 假设嵌入的订单项包含SKU字段,您将获得该SKU的所有订单.这一切都取决于架构

4> Sérgio..:

一种在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} } )



5> Ian Mercer..:

您链接到的第一个示例显示了MongoDB引用的行为方式与延迟加载非常类似,不像连接.这两个集合上都没有查询,而是查询一个,然后通过引用从另一个集合中查找项目.



6> Salah Saleh..:

mongoDB不是关系的事实导致一些人认为它没用.我认为在设计数据库之前你应该知道自己在做什么.如果您选择使用noSQL DB(如MongoDB),则最好实现架构.这将使您的集合 - 或多或少 - 类似于SQL数据库中的表.此外,避免非规范化(嵌入),除非出于效率原因需要.

如果您想设计自己的noSQL数据库,我建议您查看Firebase文档.如果您了解他们如何为其服务组织数据,您可以轻松地为您设计类似的模式.

正如其他人指出的那样,除了使用Meteor(一个Javascript框架)之外,你将不得不进行客户端连接,你可以使用这个包进行服务器端连接(我不知道其他框架可以让你做所以).但是,我建议你在决定采用这个选择之前阅读这篇文章.

编辑28.04.17: 最近Firebase发布了关于设计noSql数据库的优秀系列.他们还在其中一个剧集中强调了避免连接的原因以及如何通过非规范化数据库来解决这些问题.

推荐阅读
李桂平2402851397
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有