https://cnodejs.org/topic/59264f62855efbac2cf7a2f3

背景 现有1000条学生记录,结构如下:

{
	name:String,//名称
	clazz:{type:ObjectId,ref:"classes"},//班级id
	status:Number,//状态 1在校 2离校
	marks:[Number],//标记 1迟到 2早退 3请假
	age:Number//年龄
}

需求 要求统计1000个学生的所在班级列表,列表内容如下(模拟数据,不要在意统计的合理不合理): 班级名称 | 在校人数 | 离校人数 | 没有迟到标记的在校人数 | 没有迟到标记的在校学生的平均年龄

实现代码:

db.getCollection('students').aggregate([{
    $group: {//班级分组拿到班级id和班级内的学员信息
        _id: "$clazz",
        stus: {
            $push: "$$ROOT"
        }
    }
}, {
    $project: {
        _id: 1,
        stus: 1,
        out_num: {//计算离校人员数量
            $size: {
                $filter: {
                    input: "$stus",
                    as: "stu",
                    cond: { $eq: ["$$stu.status", 2] }
                }
            }
        },
        in_num: {//计算在校人员数量
            $size: {
                $filter: {
                    input: "$stus",
                    as: "stu",
                    cond: { $eq: ["$$stu.status", 1] }
                }
            }
        },
        in_no_1: {//计算 在校并且没有迟到标记的学员列表
            $filter: {
                input: "$stus",
                as: "stu",
                cond: { $and: [{ $eq: ["$$stu.status", 1] }, { $eq: [{ $indexOfArray: ["$$stu.marks", 1] }, -1] }] }
            }
        },
    }
}, {
    $project: {
        _id: 1,
        out_num: 1,
        in_num: 1,
        in_no_1: 1,
        in_nu_1_num: { $size: "$in_no_1" },

相关文章: