将不同列的项目值计入一个字段

时间:2018-05-09 10:27:13

标签: mongodb projection

{
    "_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'}]

- 什么是最有效的查询...?我用$ cond和$ switch尝试了$ project但是在这两种情况下我都不得不重复'subject'和'is_parent'的条件语句

- 建议在查询中进行计算,还是应该获取数据转储然后修改服务器代码中的结构?在AS中,我可以放松并获得每个子主题的父主题的映射,然后执行for循环。

我试过了

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

然后我意识到,即使我将else部分转换为子主题的另一个查询,我将不得不为is_parent的属性写出完全相同的东西

1 个答案:

答案 0 :(得分:1)

您有2个阵列,因此您需要展开两个 - reportingsubs

在该阶段之后,每个文档最多只有1个parent teacher-subj和最多1个sub teacher-subj对。

您需要再次展开它们,以便每个文档都有一个teacher-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"
        } }
    } }
])