【问题标题】:How to join multiple collections in MongoDB (one to many relationship)?如何在 MongoDB 中加入多个集合(一对多关系)?
【发布时间】:2020-09-11 19:34:11
【问题描述】:

我有两个集合:documentcitation。它们的结构如下图所示:

# document
{id:001, title:'foo'}
{id:002, title:'bar'}
{id:003, title:'abc'}

# citation
{from_id:001, to_id:002}
{from_id:001, to_id:003}

我要查询每篇文献的被引文献(称为参考文献,用to_id表示)的信息。在 SQL 中,我会使用document 表左连接citation,然后左连接document 来获取引用的完整信息(不仅仅是它们的ID)。

但是,我只能在 MongoDB 中使用$lookup 实现第一步。这是我的聚合管道:

[
    {'$lookup':{
        'from': 'citation',
        'localField': 'id',
        'foreignField': 'from_id',
        'as': 'references'
    }}
]

我可以通过这个管道获得以下结果:

{
    id:001,
    title:'foo',
    references:[{from_id:001, to_id:002}, {from_id:001, to_id:003}]
}

想要的结果是:

{
    id:001,
    title:'foo',
    references:[{id:002, title:'bar'}, {id:003, title:'abc'}]
}

我找到了这个answer,但它似乎是一对一的关系,不适用于我的情况。

编辑:有人说在 MongoDB 中应该避免加入,因为它不是关系数据库。我选择 MongoDB 是因为它比我的 MySQL 快得多。

【问题讨论】:

    标签: python database mongodb pymongo


    【解决方案1】:

    您需要在同一个集合上使用$unwind 和再次$lookup,然后您应该通过_id 使用$group 以获得所需的结果。

    试试下面的:

    [
      {
        "$lookup": {
          "from": "citation",
          "localField": "_id",
          "foreignField": "from_id",
          "as": "references"
        }
      },
      {
        "$unwind": "$references"
      },
      {
        "$lookup": {
          "from": "doc",
          "localField": "references.to_id",
          "foreignField": "_id",
          "as": "map"
        }
      },
      {
        "$unwind": "$map"
      },
      {
        "$project": {
          "_id": 1,
          "title": 1,
          "map_id": "$map._id",
          "map_title": "$map.title"
        }
      },
      {
        "$group": {
          "_id": "$_id",
          "title": {
            "$first": "$title"
          },
         "references": {
            "$push": {
              "id": "$map_id",
              "title": "$map_title"
            }
          }
        }
      }
    ]
    

    【讨论】:

    • 当你做$group时,默认只保留_id字段。因此,此运算符用于保留字段。但是,它将仅保留该分组文档中的第一个值。你可以阅读更多here
    • 谢谢!我可以在查找阶段添加约束吗?例如,一些to_id 不指向我数据库中的文档(我没有出现在参考文献中的每个文档),所以我只想要剩下的。我认为这就像一个 INNER JOIN。
    • 你可以看看this的例子。
    • 如果你能举几个这样的文件的例子和它的相应输出,也许我可以帮忙。
    • 例如,文档 001 有对文档 004 的引用,该文档不在我的数据集中。我只想查询可以绑定到我的数据集中的文档的引用。
    猜你喜欢
    • 2021-11-04
    • 2022-01-01
    • 2021-05-08
    • 2013-03-14
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多