Влияет ли несколько этапов $ проекта в агрегации MongoDB на производительность - PullRequest
0 голосов
/ 03 декабря 2018

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"
    }
]);

1 Ответ

0 голосов
/ 03 декабря 2018

Прочитайте это: https://docs.mongodb.com/v3.2/core/aggregation-pipeline-optimization/

Относительно вашего конкретного случая The aggregation pipeline can determine if it requires only a subset of the fields in the documents to obtain the results. If so, the pipeline will only use those required fields, reducing the amount of data passing through the pipeline.

Итак, за кулисами происходит некоторая оптимизация.Вы можете попробовать использовать опцию объяснения для агрегации, чтобы точно узнать, что делает Монго, чтобы попытаться оптимизировать ваш конвейер.

Я думаю, что то, что вы делаете, должно на самом деле способствовать повышению производительности, поскольку вы уменьшаете объем передаваемых данных.через.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...