如何在 MongoDB 中进行嵌套的 $lookup 搜索?

Jef*_*ian 9 mongodb mongodb-query aggregation-framework

我有 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',
    }
  }
}]
Run Code Online (Sandbox Code Playgroud)

所以我能想到的pipeline部分的代码是这样的:

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);
Run Code Online (Sandbox Code Playgroud)

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

提前致谢!

Ash*_*shh 13

$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" }
])
Run Code Online (Sandbox Code Playgroud)

随着 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" }
  }}
])
Run Code Online (Sandbox Code Playgroud)

  • 更新了我的答案 (2认同)