【问题标题】:Join two collections in MongoDB在 MongoDB 中加入两个集合
【发布时间】:2012-09-15 20:06:34
【问题描述】:

我是 mongoDB 的初学者。我有两个收藏书和作者。 [姓名和著作]分别是常用栏。使用内部连接,我必须发出 Book 和 Author 中的一些列。就像这个 sql 查询:

select book.name,book.editions,book.characters,author.name 
from dbo.book book 
inner join dbo.author author on book.name=author.works_written

我需要在 MongoDB 中执行相同的查询。映射/减少?

【问题讨论】:

标签: mongodb


【解决方案1】:

MongoDB 不支持 JOIN 操作。当您需要此功能时,您必须通过查询两个集合来自己实现它。

因此,使用嵌入而不是链接通常是一个很好的策略。

Map/Reduce 作业通常是一项非常昂贵的操作。它只应偶尔用于数据挖掘目的。

【讨论】:

  • 我需要如何使用 mapreduce 函数。
【解决方案2】:

mongodb 不是关系数据库——所以这里不可能进行任何类型的连接。连接很难扩展。

mongodb中实现join的常用方式是数据非规范化。在您的情况下,您可以将作者姓名非规范化为书表。那么您的查询将不需要加入。这是架构示例:

book
{
  _id,
  name,
  editions,
  characters,
  author_name
} 

请记住,每次更新作者收藏时,您都需要更新图书收藏中的author_name

另一种解决方案 -- 额外请求每本书的作者姓名,但它的工作速度会慢得多。

【讨论】:

  • 我需要如何使用 mapreduce 函数来做到这一点
  • @Rudra:你不能跨两个集合运行 m/r。再一次 - mongodb 不支持任何类型的连接,我在答案中列出了所有可能的解决方案。如果您需要加入 - 只需使用 sql 数据库。在 mongodb 中,您只需使用一个集合即可玩和做任何您需要的事情。
【解决方案3】:

我需要如何使用 mapreduce 函数。

db 对象在 MR 中已被弃用很长时间,因此不可能在 MR 中同时获取两个表。

还有另一种解决方案:两个 MR。您在第一个集合上运行 MR,首先输出到所需的集合,然后使用第二个 MR 输出到同一个集合,使用 out 选项(如 reducemerge)将两个集合“加入”在一起.

当然这很慢,所以最好的方法是不这样做。至于:

select book.name,book.editions,book.characters,author.name 
from dbo.book book 
inner join dbo.author author on book.name=author.works_written

这个查询可以是从图书集合中流式传输一个游标,然后非常快速地将您遍历的每本书固定在数据库中(可以在 MongoDB 中执行此操作)以获取作者详细信息。

您还可以从书籍中获取一组作者 ID,然后一次查询所有作者集合,并在客户端对两者进行排序。

【讨论】:

    【解决方案4】:

    试试这个:-

    db.book.aggregate([
        {
          $lookup:
            {
              from: "author",
              localField: "name",
              foreignField: "works_written",
              as: "nameWorkData"
            }
       }
    ])
    

    【讨论】:

      【解决方案5】:

      您可以比较以下 SQL 和 mongoDB (NoSQL) 的代码:

      • SQL 代码:

         SELECT *, [output array field]
              FROM collection
              WHERE [output array field] IN (SELECT *
                    FROM [collection to join]
                    WHERE [foreignField]= [collection.localField]);
        
      • mongoDB (NoSQL):

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

      【讨论】:

        猜你喜欢
        • 2020-05-12
        • 1970-01-01
        • 2017-08-10
        • 2020-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-22
        • 2015-10-07
        相关资源
        最近更新 更多