【问题标题】:MongoDB $lookup on multiple documents results in an empty arrayMongoDB $lookup 对多个文档的结果是一个空数组
【发布时间】:2020-12-01 03:59:26
【问题描述】:

我有 3 个收藏

  1. 图书 - 包含图书的详细信息
  2. 库 - 包含有关库的详细信息
  3. Book_Library - 每个条目都有一个 book id、library id 和一个唯一的 id book id_library id。

我知道以前有人问过这个问题,但我似乎找不到适合我的情况的解决方案。

我正在尝试从 book 中投影一个字段,从 library 中投影另一个字段,它们没有直接关系,但每个都与 book_library 有关系。然后从图书馆中按月计算类型的数量。

这是每个文档的外观。 买书

{
    "_id" : "isbn-22553564",
    "title" : "Boerworse is baie Lekker",
    "genre" : "Sci-Fi"
}

图书馆

    "_id" : "postcode-10927886",
    "postcode" : "10927886",
    "dateLoaded" : "2020-08-12"
    "town" : "Wonderland"
}

对于 book_library,它包含书籍和图书馆的 ID,其中链接源和链接目标作为此集合中的字段

{
    "_id" : "isbn-22553564_postcode-10927886",
    "lnkSrc" : "isbn-22553564",
    "lnkDst" : "postcode-10927886"
}

我想要实现的是获取流派和 dateLoaded,这样我就可以计算每年每月以接近的形式加载的“科幻”和“纪录片”书籍的数量

按月和年组合计算每个流派

{
      genre: "Sci-Fi" 
      period: "08-2020" 
      count: 20
   }
   {
      genre: "Documentary" 
      period: "09-2020" 
      count: 2
   }

我尝试使用 2 $lookup with unwind 如下

db.getCollection('book').aggregate([
                       { 
                           $lookup:{
                               localField: '_id',
                               from: 'book_library',
                               foreignField: '_id',
                               as: 'table1'
                               
                            }}, 
                            {
                                    $unwind: '$table1'
                            }, 
                            {
                                $lookup:{
                                   localField: 'lnkSrc',
                                   from: 'library',
                                   foreignField: '_id',
                                   as: 'table2'
                            }
                        }    
])

但在结果搜索中,即使我切换了哪个集合先出现,我也只会在 table2 上收到一个空数组

table2 : []

如何确保第二个表格显示结果? 我错过了什么?

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    在第一个 $lookup 上,您为 foreignField 使用了错误的字段。在您的示例中,books 集合的 _id 字段如下所示:isbn-22553564。在您的 book_library 集合中,这对应于 lnkSrc 字段。所以第一个聚合阶段应该是这样的:

    { 
      $lookup: {
        localField: '_id',
        from: 'book_library',
        foreignField: 'lnkSrc',
        as: 'table1'
      }
    }
    

    此时您的文档将具有以下形式:

    {
      "_id" : "isbn-22553564",
      "title" : "Boerworse is baie Lekker",
      "genre" : "Sci-Fi",
      "table1": [
        {
          "_id" : "isbn-22553564_postcode-10927886",
          "lnkSrc" : "isbn-22553564",
          "lnkDst" : "postcode-10927886"
        }
      ]
    }
    

    $unwind 阶段将为table1 数组中的每个元素创建一个文档,生成的文档如下:

    {
      "_id" : "isbn-22553564",
      "title" : "Boerworse is baie Lekker",
      "genre" : "Sci-Fi",
      "table1": {
        "_id" : "isbn-22553564_postcode-10927886",
        "lnkSrc" : "isbn-22553564",
        "lnkDst" : "postcode-10927886"
      }
    }
    

    请注意,现在table1 字段是一个对象而不是一个数组。

    最后的$lookup阶段需要用到table1文档中的lnkDst字段——lnkSrc指的是图书文档的_id。因为lnkDst 嵌套在table1 文档中,所以$lookup 阶段如下所示:

    { 
      $lookup: {
        localField: 'table1.lnkDst',
        from: 'library',
        foreignField: '_id',
        as: 'table2'
      }
    }
    

    当所有这些放在一起时,聚合管道如下所示:

    db.getCollection('book').aggregate([
    { 
      $lookup: {
        localField: '_id',
        from: 'book_library',
        foreignField: 'lnkSrc',
        as: 'table1'
      }
    },
    { 
      $unwind: '$table1'
    },
    { 
      $lookup: {
        localField: 'table1.lnkDst',
        from: 'library',
        foreignField: '_id',
        as: 'table2'
      }
    }])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-07
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2019-09-11
      相关资源
      最近更新 更多