Вернуть отдельный элемент из вложенного поиска с помощью запроса или - PullRequest
1 голос
/ 08 января 2020

У меня есть следующая база данных:

Запросы Коллекция

{
    "_id" : "m5tkeDo",
    "CourseId" : "KcfEGbZlyP",
    "QuizId" : "lMJkv81LyU",
    "QuestionId" : "DF9WeKATyf",
    ...
}

Викторины Коллекция

{
    "_id" : "lMJkv81LyU",
    ...
    "MultipleChoiceQuestions" : [],
    "MultipleSelectQuestions" : [],
    "TrueOrFalse" : [ 
        {
            "_id" : "DF9WeKATyf",
            ...
        }
    ],
    ...
}

Использование поиск Я могу получить Quiz от Request:

db.getCollection('Requests').aggregate([
    { $match: { _id: "m5tkeDo" } },
    {
        $lookup: {
            from: "Quizzes",
            localField: "QuizId",
            foreignField: "_id",
            as: "Quiz"
         }
     },
     { $unwind: "$Quiz" }
]);

, который возвращает что-то вроде этого

{
    "_id" : "m5tkeDo",
    "QuizId" : "lMJkv81LyU",
    "QuestionId" : "DF9WeKATyf",
    ...
    "Quiz" : {
        "_id" : "lMJkv81LyU",
        ...
        "MultipleChoiceQuestions" : [],
        "MultipleSelectQuestions" : [],
        "TrueOrFalse" : [ 
            {
                "_id" : "DF9WeKATyf",
                ...
            }
        ],
        ...
    }
}

То, что я пытаюсь выяснить, это Могу ли я получить вопрос, который является объектом в массиве TrueOrFalse Quiz? Неизвестно, будет ли коллекция элементом массива TrueOrFalse, MultipleChoiceQuestions или MultipleSelectQuestions, поэтому мне нужно просмотреть все из них.

Конечный результат выглядит примерно так:

{
    "_id" : "m5tkeDo",
    "QuizId" : "lMJkv81LyU",
    "QuestionId" : "DF9WeKATyf",
    ...
    "Quiz" : {
        ...
    },
    "Question": {
      "_id" : "DF9WeKATyf",
       ...
    }

}

1 Ответ

0 голосов
/ 08 января 2020

Пожалуйста, попробуйте это:

db.getCollection('Requests').aggregate([
    { $match: { _id: "m5tkeDo" } },
    {
        $lookup: {
            from: "Quizzes",
            localField: "QuizId",
            foreignField: "_id",
            as: "Quiz"
        }
    }, { $unwind: '$Quiz' },
    {
        $addFields: {
            QuestionIdObj: {
                $arrayElemAt: [{
                    $filter: {
                        input: { $concatArrays: ["$Quiz.MultipleChoiceQuestions", "$Quiz.MultipleSelectQuestions", "$Quiz.TrueOrFalse"] },
                        as: "item",
                        cond: { $eq: ["$$item._id", '$QuestionId'] }
                    }
                }, 0]
            }
        }
    }
])

Это будет работать, даже если QuestionId существует в любом из 3 массивов или даже во всех 3 массивах. QuestionIdObj будет либо обязательным объектом, либо null, как мы делаем $filter, он вернет null (если в массиве concat'd из трех массивов не найдено совпадений QuestionId).

Результат:

/* 1 */
{
    "_id" : "m5tkeDo",
    "CourseId" : "KcfEGbZlyP",
    "QuizId" : "lMJkv81LyU",
    "QuestionId" : "DF9WeKATyf",
    "Quiz" : {
        "_id" : "lMJkv81LyU",
        "MultipleChoiceQuestions" : [],
        "MultipleSelectQuestions" : [],
        "TrueOrFalse" : [ 
            {
                "_id" : "DF9WeKATyf"
            }, 
            {
                "_id" : "DF9WeKATyf1"
            }
        ]
    },
    "QuestionIdObj" : {
        "_id" : "DF9WeKATyf"
    }
}
...