zoukankan      html  css  js  c++  java
  • 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的各种操作命令(尤其是数组的)。好了笔记就记录这些了。有更好的解决方案,大家一起讨论。

  • 相关阅读:
    iOS如何隐藏状态栏,包括网络标志、时间标志、电池标志等
    xcrun: error: active developer path
    我们很少有机会看到一个人的所有面
    默妹(二)
    Bootstrap3的响应式缩略图幻灯轮播效果设计
    纯CSS3实现图片展示特效
    解决div设置浮动,高度消失
    解决css设置背景透明,文字不透明
    从零开始学习jQuery (六) jquery中的AJAX使用
    如何利用开源思想开发一个SEO友好型网
  • 原文地址:https://www.cnblogs.com/jayruan/p/7248168.html
Copyright © 2011-2022 走看看