Спроектируйте значения разных столбцов в одно поле - PullRequest
0 голосов
/ 09 мая 2018
{
    "_id" : ObjectId("5ae84dd87f5b72618ba7a669"),
    "main_sub" : "MATHS",
    "reporting" : [ 
        {
            "teacher" : "ABC"
        }
    ],
    "subs" : [ 
        {
            "sub" : "GEOMETRIC",
            "teacher" : "XYZ",
        }
    ]
}
{
    "_id" : ObjectId("5ae84dd87f5b72618ba7a669"),
    "main_sub" : "SOCIAL SCIENCE",
    "reporting" : [ 
        {
            "teacher" : "XYZ"
        }
    ],
    "subs" : [ 
        {
            "sub" : "CIVIL",
            "teacher" : "ABC",
        }
    ]
}

Я упростил структуру документов, которые у меня есть. Основная структура состоит в том, что у меня есть родительский предмет с массивом учителей-репортеров и массивом суб-предметов (каждый из которых имеет учителя)

Теперь я хочу извлечь все предметы (родительские / под-предметы) вместе с условием, являются ли они под-предметами или нет, которые преподаются конкретным учителем.

Например:

для учителя ABC я хочу следующую структуру:

[{'subject':'MATHS', 'is_parent':'True'}, {'subject':'CIVIL', 'is_parent':'FALSE'}]

- Какой самый эффективный запрос возможен ..? Я пробовал $ project с $ cond и $ switch, но в обоих случаях мне пришлось повторить условный оператор для 'subject' и 'is_parent'

- Рекомендуется ли выполнять вычисления в запросе или мне нужно получить дамп данных и затем изменить структуру в коде сервера? После этого я мог бы $ $ развернуть и получить сопоставление родительских предметов с каждым подчиненным субъектом, а затем выполнить цикл for.

Я пытался

db.collection.aggregate(
    {$unwind:'$reporting'},
    {$project:{
        'result':{$cond:[
            {$eq:['ABC', '$reporting.teacher']}, 
            "$main_sub", 
            "$subs.sub"]}
    }}
) 

тогда я понял, что даже если я преобразую остальную часть в другой запрос для поддоменов, мне придется написать то же самое для свойства is_parent

1 Ответ

0 голосов
/ 10 мая 2018

У вас есть 2 массива, поэтому вам нужно развернуть оба - reporting и subs.

После этого этапа каждый документ будет содержать не более 1 пары учитель-подчиненный и не более 1 пары учитель-подчинение.

Вам нужно снова размотать их, чтобы иметь по одному учителю-subj на документ, и именно здесь вы определяете, является ли он родительским или нет.

Тогда вы можете группировать по учителю. Нет необходимости в $ conds, $ filters или $ facets. E.g.:

db.collection.aggregate([
    { $unwind: "$reporting" },
    { $unwind: "$subs" },
    { $project: {
        teachers: [ 
            { teacher: "$reporting.teacher", sub: "$main_sub", is_parent: true }, 
            { teacher: "$subs.teacher", sub: "$subs.sub", is_parent: false }
        ]
    } },
    { $unwind: "$teachers" },
    { $group: {
        _id: "$teachers.teacher",
        subs: { $push: {
            subject: "$teachers.sub", 
            is_parent: "$teachers.is_parent"
        } }
    } }
])
...