MongoDB 和“加入”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4067197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 11:51:17  来源:igfitidea点击:

MongoDB and "joins"

mongodb

提问by TK.

I'm sure MongoDB doesn't officially support "joins". What does this mean?

我确定 MongoDB 不正式支持“加入”。这是什么意思?

Does this mean "We cannot connect two collections(tables) together."?

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

I think if we put the value for _idin collection A to the other_idin collection B, can we simply connect two collections?

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

If my understanding is correct, MongoDB can connect two tables together, say, when we run a query. This is done by "Reference" written in http://www.mongodb.org/display/DOCS/Schema+Design.

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

Then what does "joins" really mean?

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

I'd love to know the answer because this is essential to learn MongoDB schema design. http://www.mongodb.org/display/DOCS/Schema+Design

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

采纳答案by Emil Vikstr?m

It's no join since the relationship will only be evaluated when needed. A join (in a SQL database) on the other hand will resolve relationships and return them as if they were a single table (you "join two tables into one").

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

You can read more about DBRef here: http://docs.mongodb.org/manual/applications/database-references/

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

There are two possible solutions for resolving references. One is to do it manually, as you have almost described. Just save a document's _id in another document's other_id, then write your own function to resolve the relationship. The other solution is to use DBRefs as described on the manual page above, which will make MongoDB resolve the relationship client-sideon demand. Which solution you choose does not matter so much because both methods will resolve the relationship client-side (note that a SQL database resolves joins on the server-side).

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

回答by Clayton Gulick

As of Mongo 3.2 the answer to this question is no longer correct. The new $lookup operator added to the aggregation pipeline is essentially identical to a left outer join:

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

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

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

From the docs:

从文档:

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

回答by dm.

The database does not do joins -- or automatic "linking" between documents. However you can do it yourself client side. If you need to do 2, that is ok, but if you had to do 2000, the number of client/server turnarounds would make the operation slow.

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

In MongoDB a common pattern is embedding. In relational when normalizing things get broken into parts. Often in mongo these pieces end up being a single document, so no join is needed anyway. But when one is needed, one does it client-side.

在 MongoDB 中,一个常见的模式是嵌入。在关系规范化时,事情会被分解成部分。通常在 mongo 中,这些部分最终会成为一个单独的文档,因此无论如何都不需要加入。但是,当需要时,可以在客户端进行。

Consider the classic ORDER, ORDER-LINEITEM example. One order and 8 line items are 9 rows in relational; in MongoDB we would typically just model this as a single BSON document which is an order with an array of embedded line items. So in that case, the join issue does not arise. However the order would have a CUSTOMER which probably is a separate collection - the client could read the cust_id from the order document, and then go fetch it as needed separately.

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

There are some videos and slides for schema design talks on the mongodb.org web site I belive.

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

回答by Sérgio

one kind of join a query in mongoDB, is ask at one collection for id that match , put ids in a list (idlist) , and do find using on other (or same) collection with $in : idlist

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

回答by Salah Saleh

The fact that mongoDB is not relational have led some people to consider it useless. I think that you should know what you are doing before designing a DB. If you choose to use noSQL DB such as MongoDB, you better implement a schema. This will make your collections - more or less - resemble tables in SQL databases. Also, avoid denormalization (embedding), unless necessary for efficiency reasons.

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

If you want to design your own noSQL database, I suggest to have a look on Firebasedocumentation. If you understand how they organize the data for their service, you can easily design a similar pattern for yours.

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

As others pointed out, you will have to do the joins client-side, except with Meteor(a Javascript framework), you can do your joins server-side with this package(I don't know of other framework which enables you to do so). However, I suggest you read this articlebefore deciding to go with this choice.

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

Edit 28.04.17:Recently Firebase published this excellent serieson designing noSql Databases. They also highlighted in one of the episodesthe reasons to avoid joins and how to get around such scenarios by denormalizing your database.

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

回答by Ian Mercer

The first example you link to shows how MongoDB references behave much like lazy loading not like a join. There isn't a query there that's happening on both collections, rather you query one and then you lookup items from another collection by reference.

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

回答by pfrank

Consider using mongoose? It gives you the ability to do joins on mongo data.

考虑使用猫鼬?它使您能够对 mongo 数据进行连接。

回答by Daniel Kmak

If you use mongoose, you can just use(assuming you're using subdocuments and population):

如果您使用猫鼬,则可以使用(假设您使用的是子文档和人口):

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

It retrieves Statuseswhich belong to one of Profile(profileId) friends. Friends is array of references to other Profiles. Profileschema with friendsdefined:

它检索Statuses属于Profile( profileId) 个朋友之一。Friends 是对 other 的引用数组ProfilesProfile具有friends定义的架构:

schema = new mongoose.Schema
  # ...

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

回答by Amine_Dev

you can use MongoDB addons , it's greate , and allow to join , merge and create a query builer try it : https://github.com/petersirka/mongodb-addons

您可以使用 MongoDB 插件,它很棒,并允许加入、合并和创建查询构建器试试看:https: //github.com/petersirka/mongodb-addons

回答by Utsav T

Being a user of MongoDB myself, I had to fetch data from related collections rather frequently. When people store data of relational databases into NoSQL databases, "joining" does become necessary. Here's a library that I, along with my friend, have made to perform Mongo Joins in Python -

作为 MongoDB 的用户,我不得不频繁地从相关集合中获取数据。当人们将关系型数据库的数据存储到 NoSQL 数据库中时,“加入”确实是必要的。这是我和我的朋友一起制作的一个库,用于在 Python 中执行 Mongo Joins -

https://pypi.python.org/pypi/mongojoin/1.0.0

https://pypi.python.org/pypi/mongojoin/1.0.0

The code isn't too complicated and well worth a try !

代码不太复杂,值得一试!