如何使用 MongoDB 聚合的条件查找

how to use lookup with a condition using MongoDB aggregation

有两个 collection 值

如何使用 MongoDB 聚合

的条件查找

第一个collection:basic_info

[
 {
    _id: "bmasndvhjbcw",
    name: "lucas",
    occupation: "scientist",
    present_working:true,
    age: 55,
    location: "texas",

  },
  {
    _id: "bmasndvhjbcx",
    name: "mark",
    occupation: "scientist",
    age: 45,
    present_working:true,
    location: "texas",
  },
  {
    _id: "bmasndvhjbcq",
    name: "cooper",
    occupation: "physicist",
    age: 69,
    location: "texas"
  }
]

秒 collection : test_results

[
 {
    basic_id: "bmasndvhjbcw",
    test_results:"PASS",

  },
  {
    basic_id: "bmasndvhjbcx",
    test_results:"PASS",
  },
  {
    basic_id: "bmasndvhjbcq",
    test_results:"FAIL",
  }
]

查找 test_results: PASStest_results: FAIL, 应被排除的条件

expected_output 使用查找聚合后:

[
 {
    _id: "bmasndvhjbcw",
    name: "lucas",
    occupation: "scientist",
    present_working:true,
    age: 55,
    location: "texas",
    test_results:"PASS"

  },
  {
    _id: "bmasndvhjbcx",
    name: "mark",
    occupation: "scientist",
    age: 45,
    present_working:true,
    location: "texas",
    test_results:"PASS"
  }
]

MongoDB版本:4.0

从MongoDB v3.6开始,我们可以用$lookup执行uncorrelated sub-queries

它 returns 来自 test_results 集合 0 ... N 的匹配结果列表(在您的情况下,它将是 0 ... 1)。下一步,我们过滤空 test_results 字段(不匹配的文档)。

在最后阶段,我们将文档转换为所需的输出结果。 $replaceRoot 运算符允许变换:

{                                      {
  ... other fields                       ... other fields
  test_results : [           ---->
    {test_results:"PASS"}    ---->       test_results:"PASS"
  ]
}                                      }

试试下面的查询:

db.basic_info.aggregate([
  {
    $lookup: {
      from: "test_results",
      let: {
        id: "$_id"
      },
      pipeline: [
        {
          $match: {
            test_results: "PASS",
            $expr: {
              $eq: [
                "$basic_id",
                "$$id"
              ]
            }
          }
        },
        {
          $project: {
            _id: 0,
            test_results: 1
          }
        }
      ],
      as: "test_results"
    }
  },
  {
    $match: {
      "test_results.0": {
        $exists: true
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          "$$ROOT",
          {
            $arrayElemAt: [
              "$test_results",
              0
            ]
          }
        ]
      }
    }
  }
])

MongoPlayground

技巧: 由于您只需要 test_results 集合中的 test_results:"PASS",我们可以将 $replaceRoot 更改为 $addFields

{
  $addFields: {
    test_results: "PASS"
  }
}