как использовать поиск с условием агрегирования MongoDB - PullRequest
0 голосов
/ 30 марта 2020

имеют две коллекции со значениями

как использовать поиск с условием с использованием агрегации MongoDB

первая коллекция: 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"
  }
]

вторая коллекция: test_results

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

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

Поиск с условием, где test_results: PASS и test_results: FAIL, должны быть исключены

ожидаемый_производительность после агрегирования с использованием поиска:

[
 {
    _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

1 Ответ

1 голос
/ 30 марта 2020

Начиная с MongoDB v3.6, мы можем выполнять некоррелированные подзапросы с $lookup.

Возвращает список совпадающих результатов из test_results collection 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

Trick : Так как вам нужно только test_results:"PASS" из test_results коллекции, мы можем изменить $replaceRoot на $addFields:

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