聚合框架需要将字段值与组总数相匹配

时间:2017-04-24 19:02:01

标签: mongodb match aggregation-framework

我有一系列学生文件,如:

{
        "_id" : 1,
        "Student" : "Sim",
        "Test1" : 59,
        "Test2" : 94,
        "Test3" : 81
}
{
        "_id" : 2,
        "Student" : "Sam",
        "Test1" : 60,
        "Test2" : 77,
        "Test3" : 81
}

我需要使用聚合框架来优化Test1得分低于整个班级所有测试的总平均值的学生的名字。

我可以在以下组中获得总平均值,但是,,,

如果

db.students.aggregate([
    {$project: { 
        Stu: '$Student',
        Test1: '$Test1',
        av: {$avg: ['$Test1', '$Test2', '$Test3']} 
    } },
    {$group: { _id: null, 
                totAvg: {$avg : '$av'} 
    }
 ]);

那时我失去了学生和test1在比赛部分进行比较。

1 个答案:

答案 0 :(得分:1)

使用$push + $filter

$push阶段中的

$group,以便在test1阶段将所有Student标记和$filter名称后跟$project进行比较总平均标记并保留匹配记录。

您可以将$filter打包在$map中,仅投影学生姓名。

db.students.aggregate([{
        $project: {
            Stu: '$Student',
            Test1: '$Test1',
            av: {
                $avg: ['$Test1', '$Test2', '$Test3']
            }
        }
    },
    {
        $group: {
            _id: null,
            studentTest1: {
                $push: {
                    "Student": "$Stu",
                    "Test1": "$Test1"
                }
            },
            totAvg: {
                $avg: '$av'
            }
        }
    },
    { $project:
     { lessthanAvgStudentNames:
        {
          $map:
             {
               input: {
                    $filter: {
                        input: "$studentTest1",
                        as: "resultf",
                        cond: {
                            $lt: ["$$resultf.Test1", "$totAvg"]
                        }
                    }
                },
               as: "resultm",
               in: "$$resultm.Student"
             }
        }
     }
   }
]);