MongoDB 和“连接”

我敢肯定 MongoDB 并不正式支持“连接”。这是什么意思?

这是否意味着“我们不能将两个集合(表)连接在一起”?

我认为如果我们将集合 A 中的 _id的值放到集合 B 中的 other_id,我们能简单地连接两个集合吗?

如果我的理解是正确的,MongoDB 可以在运行查询时将两个表连接在一起。这是由 http://www.mongodb.org/display/DOCS/Schema+Design中编写的“参考”完成的。

那“加入”到底是什么意思?

我很想知道答案,因为这对于学习 MongoDB 模式设计是必不可少的

155697 次浏览

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

你可以在这里了解更多关于 DBRef 的信息: Http://docs.mongodb.org/manual/applications/database-references/

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

您链接到的第一个示例显示 MongoDB 引用的行为与延迟加载非常相似,而与联接不同。在这两个集合中都没有查询,而是先查询一个集合,然后通过引用从另一个集合中查找项。

数据库不进行连接——或文档之间的自动“链接”。无论如何,你可以做自己的客户端。如果需要执行2,那没问题,但如果必须执行2000,客户机/服务器周转的次数会使操作变慢。

在 MongoDB 中,一个常见的模式是嵌入。在关系中,当正常化的事物被分成几部分时。通常在 mongo 中,这些部分最终成为一个单独的文档,因此无论如何都不需要连接。但是当需要的时候,人们会在客户端进行。

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

我相信在 mongodb.org 网站上有一些关于模式设计的视频和幻灯片。

在 mongoDB 中联接查询的一种方式是,在一个集合中请求匹配的 id,将 id 放入列表(idlist)中,并使用 $in: idlist 在其他(或相同)集合上执行 find

u = db.friends.find({"friends": something }).toArray()
idlist= []
u.forEach(function(myDoc) { idlist.push(myDoc.id ); } )
db.family.find({"id": {$in : idlist} } )

如果您使用猫鼬,您可以只使用(假设您使用子文档和填充) :

Profile.findById profileId
.select 'friends'
.exec (err, profile) ->
if err or not profile
handleError err, profile, res
else
Status.find { profile: { $in: profile.friends } }, (err, statuses) ->
if err
handleErr err, statuses, res
else
res.json createJSON statuses

它检索属于 Profile(profileId)好友之一的 Statuses。Friends 是对其他 Profiles的引用数组。定义了 friendsProfile模式:

schema = new mongoose.Schema
# ...


friends: [
type: mongoose.Schema.Types.ObjectId
ref: 'Profile'
unique: true
index: true
]

MongoDB 不是关系型的事实导致了 有些人认为这是没有用的。 我认为在设计数据库之前,你应该知道你在做什么。如果您选择使用 noSQLDB,比如 MongoDB,那么您最好实现一个模式。这将使您的集合(或多或少)类似于 SQL 数据库中的表。另外,避免反规范化(嵌入) ,除非出于效率方面的原因。

如果您想设计自己的 noSQL 数据库,我建议您查看一下 火力点文档。如果您了解他们如何组织服务的数据,就可以很容易地为您的服务设计类似的模式。

正如其他人指出的,您必须在客户端进行连接,除了使用 流星(一个 Javascript 框架)之外,您可以在服务器端使用这个 包裹(我不知道还有什么其他框架允许您这样做)进行连接。但是,我建议您在决定使用这个选项之前先阅读这个 文章

编辑28.04.17: 最近 Firebase 在设计 noSql 数据库时发布了这个 精彩的系列。他们还在 其中一集中强调了避免连接的原因,以及如何通过反规范化数据库来避免这种情况。

我发现很多帖子都在搜索相同的东西——“ Mongodb 连接”和其他替代品或等价物。所以我的答案会帮助很多像我一样的人。这就是我想要的答案。

我使用的是带有 Express 框架的 Mongoose。

正如在猫鼬 医生中提到的。

MongoDB 中没有连接,但有时我们仍然希望引用其他集合中的文档。这就是人口增长的原因。

这个 StackOverflow 回答展示了一个关于如何使用它的简单示例。