TL; DR
Мы добавляем $project
этап между $match
и $lookup
этапом, чтобы отфильтровать ненужные данные или наложить псевдонимы на поля.* Этапы улучшают способность чтения запроса при отладке, но влияют ли они на производительность, когда в каждой коллекции, участвующей в запросе, содержится большое количество документов.
Вопрос подробный
Например, у меня есть две коллекции школ и учеников , как показано ниже:
Да, схема плохая, я знаю!MongoDB говорит - поместите все в одну коллекцию, чтобы избежать отношений, но давайте пока продолжим этот подход.
школ коллекция
{
"_id": ObjectId("5c04dca4289c601a393d9db8"),
"name": "First School Name",
"address": "1 xyz",
"status": 1,
// Many more fields
},
{
"_id": ObjectId("5c04dca4289c601a393d9db9"),
"name": "Second School Name",
"address": "2 xyz",
"status": 1,
// Many more fields
},
// Many more Schools
ученик collection
{
"_id": ObjectId("5c04dcd5289c601a393d9dbb"),
"name": "One Student Name",
"school_id": ObjectId("5c04dca4289c601a393d9db8"),
"address": "1 abc",
"Gender": "Male",
// Many more fields
},
{
"_id": ObjectId("5c04dcd5289c601a393d9dbc"),
"name": "Second Student Name",
"school_id": ObjectId("5c04dca4289c601a393d9db9"),
"address": "1 abc",
"Gender": "Male",
// Many more fields
},
// Many more students
Теперь в моем запросе, как показано ниже, у меня есть $project
этап после $match
непосредственно перед $lookup
.Так необходим ли этот $project
этап?Повлияет ли этот этап на производительность при наличии большого количества документов во всех коллекциях, задействованных в запросе?
db.students.aggregate([
{
$match: {
"Gender": "Male"
}
},
// 1. Below $project stage is not necessary apart from filtering out and aliasing.
// 2. Will this stage affect performance when there are huge number of documents?
{
$project: {
"_id": 0,
"student_id": "$_id",
"student_name": "$name",
"school_id": 1
}
},
{
$lookup: {
from: "schools",
let: {
"school_id": "$school_id"
},
pipeline: [
{
$match: {
"status": 1,
$expr: {
$eq: ["$_id", "$$school_id"]
}
}
},
{
$project: {
"_id": 0,
"name": 1
}
}
],
as: "school"
}
},
{
$unwind: "$school"
}
]);