【问题标题】:How to do nested $lookup search in MongoDB?如何在 MongoDB 中进行嵌套的 $lookup 搜索?
【发布时间】:2018-10-09 01:48:00
【问题描述】:

我有 3 个收藏:

  1. 职位:
+------------------+----------+------ ----------------+ | position_id | company_id |位置名 | +------------------+----------+------ ----------------+ | 1 | 1 |位置 1 | +------------------+----------+------ ----------------+ | 2 | 2 |位置 2 | +------------------+----------+------ ----------------+
  1. 公司:
+------------------+----------+------ ----------------+ | company_id |行业ID |公司名称 | +------------------+----------+------ ----------------+ | 1 | 1 |公司 1 | +------------------+----------+------ ----------------+ | 2 | 2 |公司 2 | +-------------------------------------------------- ----------------+
  1. 行业:
+------------------+----------+ |行业ID |行业名称 | +------------------+----------+ | 1 |工业1 | +------------------+----------+ | 2 |工业2 | +------------------+----------+

我需要在一个 API 中返回以下结果:

[{
  position_id: 1,
  position_name: 'position 1',
  company: {
    company_id: 1,
    company_name: 'company 1',
    industry: {
      industry_id: 1,
      industry_name: 'industry 1',
    }
  }
}, {
  position_id: 2,
  posiiton_name: 'position 2',
  company: {
    company_id: 2,
    company_name: 'company 2',
    industry: {
      industry_id: 2,
      industry_name: 'industry 2',
    }
  }
}]

所以我能想到的管道部分的代码如下:

const pipelines = [{
  $lookup: {
    from: 'companies',
    localField: 'company_id',
    foreignField: 'company_id',
    as: 'company',

    $lookup: {
      from: 'industries',
      localField: 'industry_id',
      foreignField: 'industry_id',
      as: 'industry'
    }
  }
}]

return positions.aggregate(pipelines);

但这会引发一些错误。那么在 mongodb 搜索中进行嵌套 $lookup 的正确方法是什么?

提前致谢!

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    $lookup 3.6 语法允许您连接嵌套表,$unwind 可以从输入文档中解构一个数组字段,从而为每个元素输出一个文档。像这样的

    position.aggregate([
      { "$lookup": {
        "from": "companies",
        "let": { "companyId": "$company_id" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": [ "$_id", "$$companyId" ] } } },
          { "$lookup": {
            "from": "industries",
            "let": { "industry_id": "$industry_id" },
            "pipeline": [
              { "$match": { "$expr": { "$eq": [ "$_id", "$$industry_id" ] } } }
            ],
            "as": "industry"
          }},
          { "$unwind": "$industry" }
        ],
        "as": "company"
      }},
      { "$unwind": "$company" }
    ])
    

    3.4版本

    position.aggregate([
      { "$lookup": {
        "from": "companies",
        "localField": "company_id",
        "foreignField": "_id",
        "as": "companies"
      }},
      { "$unwind": "$companies" },
      { "$lookup": {
        "from": "industries",
        "localField": "companies.industry_id",
        "foreignField": "_id",
        "as": "companies.industry"
      }},
      { "$unwind": "$companies.industry" },
      { "$group": {
        "_id": "$_id",
        "companies": { "$push": "$companies" }
      }}
    ])
    

    【讨论】:

    • 您好,我尝试了您的解决方案,它在我的本地计算机上运行良好!谢谢!但是在代码合并到生产环境后,它声称MongoError: arguments to $lookup must be strings, let: { companyId: "$companyId" } is type object。然后我发现服务器使用的是 mongodb 3.4。我应该如何更改代码以使其与 mongodb 3.4 兼容?
    • 可以用3.4版本完成,但是会很冗长而且性能开销很大。所以如果你更新你的服务器版本会更好。
    • 更新了我的答案
    • 酷,非常感谢!
    • @Tadej 但是性能方面 3.6 更好
    猜你喜欢
    • 2020-02-09
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    相关资源
    最近更新 更多