• mongo aggregate


    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" },//计算在校并且没有迟到标记的学员数量
            avg: {//计算在校并且没有迟到标记的学员的平均年龄
                $cond: {
                    if: { $eq: [{ $size: "$in_no_1" }, 0] },//如果班级内没有符合条件的学生则年龄记为0
                    then: 0,
                    else: {//班级内有符合条件的学生,计算学生年龄总和并除以学生数量
                        $divide: [{
                            $reduce: {
                                input: "$in_no_1",
                                initialValue: 0,
                                in : { $add: ['$$value', "$$this.age"] }
                            }
                        }, {
                            $size: "$in_no_1"
                        }]
                    }
                }
            }
        }
    }, {
        $lookup: {//关联查询班级信息,关联信息返回为数组
            from: "classes",
            localField: "_id",
            foreignField: "_id",
            as: "clazz"
        }
    }, {
        $unwind: '$clazz'//拆分班级返回信息数组
    
    }, {
        $project: {//整理最后的数据
            _id: 1,
            out_num: 1,
            in_num: 1,
            avg: 1,
            in_nu_1_num: 1,
            name: '$clazz.name'
        }
    }])

    代码就这些,需要看的是aggregate的各种操作命令(尤其是数组的)。好了笔记就记录这些了。有更好的解决方案,大家一起讨论。

  • 相关阅读:
    JBDC链接数据库
    js操作BOM对象
    打印倒正三角形
    window.onload事件
    js动态改变样式属性(className属性)
    js动态改变样式属性(style属性)
    js操作DOM对象(节点的增删改)
    easygen通用代码生成框架[开源]
    什么是真正的幸福与成功
    JVM学习笔记八:线程安全与锁优化
  • 原文地址:https://www.cnblogs.com/jayruan/p/7248168.html
Copyright © 2020-2023  润新知