【MongoDB】--MongoDB聚合Aggregation

这篇具有很好参考价值的文章主要介绍了【MongoDB】--MongoDB聚合Aggregation。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

聚合操作组值来自多个文档,可以对分组数据执行各种操作以返回单个结果。聚合操作包含三类:单一作用聚合、聚合管道、MapReduce

  • 单一作用聚合:提供对常见聚合过程的简单访问,操作都从单个集合聚合文档
  • 聚合管道操作:将文档在一个管道处理完毕后,把处理的结果传递给下一个管道进行再次处理
  • MapReduce操作:是将集合中的批量文档进行分解处理,然后将处理后的各个结果进行合并输出

二、聚合管道操作

管道的主要函数方法如下:

名称	                描述	                  类比sql
$avg	      计算均值	   avg
$first	  返回每组第一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序返回第一个文档。 	  limit 0,1
$last	返回每组最后一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序返回最后一个文档。	 -
$max	根据分组,获取集合中所有文档对应值的最大值。	 max
$min	根据分组,获取集合中所有文档对应值的最小值。	 min
$push	将指定的表达式的值添加到一个数组中。	 -
$addToSet	将表达式的值添加到一个集合中(无重复值,无序)。	-
$sum	计算总和	 sum
$stdDevPop	返回输入值的总体标准偏差(population standard deviation)	-
$stdDevSamp	返回输入值的样本标准偏差(the sample standard deviation)	-

2.1、实际案例1

classDo是班级信息
StudentDo是学生信息
teacherDo是老师信息

 一个学生 关联一个班级;一个班级有多个学生;
 一个老师挂在多个班级下;一个班级拥有多个老师;

主要表结构字段:

ClassDo班级信息
   @JSONField(name = "class_no")
    private String classNo;
    @JSONField(name = "class_name")
    private String className;
    @JSONField(name = "class_position")
    private String classPosition;
 
    List<StudentDo> studentDos; //关联学生们
    List<TeacherDo> teacherDos; //关联老师们

StudentDo学生信息
   @JSONField(name = "stu_id")
    private String stuId;
    @JSONField(name = "stu_name")
    private String stuName;
    @JSONField(name = "stu_age")
    private String stuAge;
    @JSONField(name = "chinese_score")
    private String chineseScore;
    @JSONField(name = "match_score")
    private String matchScore;
    @JSONField(name = "class_id")
    private ObjectId classId; //学生属于哪个班级
    
    ClassDo classDo; //学生属于具体哪个班

TeacherDo老师信息
    @JSONField(name = "te_id")
    private String teId;
    @JSONField(name = "te_name")
    private String teName;
    @JSONField(name = "te_age")
    private String teAge;
    @JSONField(name = "class_ids")
    private List<ObjectId> classIds; //老师教学多个班级
   

(1)、案例–根据学生no,找到对应班级名称

    public void aggregateStudent(String stuName,String stuAge){
        int page =2,maxElements=10;
        Criteria criteria = new Criteria();
        criteria.and("stuName").is(stuName);
        criteria.and("stuAge").is(stuAge);
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.lookup("w_class","classId","_id","classDo"),
//                Aggregation.unwind("classDo") //加上这行,那么classDo关联时,classDo节点为null,那么就去去掉这一行
                Aggregation.unwind("classDo",true), //classDo为null,这个数组[index]还存在,但classDo字段不存在了
                //  计算思路:skip((页码-1)* maxElements)
                Aggregation.sort(Sort.by("stu_age").descending()),
                Aggregation.skip((page-1)*maxElements),
                //  利用limit:限制输出的文档数,即需展示的数据量(可理解为每页显示的数量)
                Aggregation.limit(maxElements)
        );
        /**
         * aggregate()表明 主要查询w_student表,对应的查询条件是match(criteria);
         * 接着要关联w_class表。  w_student表的class_id字段关联w_class表的_id字段。
         */
        AggregationResults<JSONObject> aggregationResults = mongoTemplate.aggregate(aggregation, "w_student", JSONObject.class);
        List<JSONObject> infoList = aggregationResults.getMappedResults();
        log.info("aggregationResults:{}", JSON.toJSONString(infoList));

    }

(2)、案例–这个班级有哪些学生和哪些老师在任课

备注:主表有查询条件;关联两个子表;以主表返回结果

  public void aggregateClass(String className){
        Criteria criteria = new Criteria();
        criteria.and("className").is(className);
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.lookup("w_student","_id","classId","studentDos"),
                Aggregation.lookup("w_teacher","_id","classIds","teacherDos")
        );
        AggregationResults<JSONObject> aggregationResults = mongoTemplate.aggregate(aggregation, "w_class", JSONObject.class);
        List<JSONObject> infoList = aggregationResults.getMappedResults();
        log.info("aggregationResults:{}", JSON.toJSONString(infoList));

    }

2.2、实际案例2

现有两个mongodb表,business_permission存储某个业务的权限信息;business_a表是具体某个业务;其中business_a表的主键id关联到business_permission表的business_id。

(1)、案例–主表和关联表都有条件限制,且分页返回

由于这里的查询要求分页,那么只能对要分页的主表进行返回。文章来源地址https://www.toymoban.com/news/detail-621664.html

  public Object templateAggregation2(int page,int size){
         //主表的查询条件
        Criteria criteria = new Criteria();
        criteria.and("state").is(Boolean.TRUE);
        //关联表的查询条件
        Criteria permissionCri = new Criteria();
        permissionCri.and("templateInfo.business_type").is(7); 

        //
        /**
        templateInfo是关联的表结构;这个结构的permission节点是一个数组,在具体按照要求进行过滤得到需要的权限是否存在
        */
        Criteria businessCriteria = new Criteria();  businessCriteria.andOperator(Criteria.where("templateInfo.permission.id").is("04"),Criteria.where("templateInfo.permission.permission_type").is(2));
        Criteria businessCriteria2 = new Criteria();
businessCriteria2.andOperator(Criteria.where("templateInfo.permission.id").is("01"),Criteria.where("templateInfo.permission.permission_type").is(2));
        List<Criteria> busCriteriaList = new ArrayList<>();
        busCriteriaList.add(businessCriteria);
        busCriteriaList.add(businessCriteria2);
        busCriteriaList.add(Criteria.where("templateInfo.all_flag").is(Boolean.TRUE));
        busCriteriaList.add(Criteria.where("templateInfo.permission").is(null));
        busCriteriaList.add(Criteria.where("templateInfo.permission").is(new ArrayList<>()));
        Criteria[] criArray = new Criteria[busCriteriaList.size()];
        busCriteriaList.toArray(criArray);
        permissionCri.orOperator(criArray);

        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria), //主mongodb自身查询条件
                Aggregation.lookup("business_permission","_id","business_id","templateInfo"), //business_permission的business_id对应主表的id
                Aggregation.match(permissionCri), //关联表查询条件
                Aggregation.sort(new Sort(Sort.Direction.DESC, "update_time")),
                 //  计算思路:skip((页码-1)* maxElements)
                 Aggregation.skip((page-1)*size),
                 Aggregation.limit(size)  //这分页的
              //  Aggregation.group("template_type") //按照分组返回特定的字段值 【可以统计数量】
             //   .sum("id").as("sumValue")  //对id进行求和 
             //   .first("template_code").as("templateCode")
             //   .avg("doc_view_number").as("avgValue")
        );

        AggregationResults<JSONObject> aggregationResults = mongoTemplate.aggregate(aggregation, "business_a", JSONObject.class);
        List<JSONObject> templateList = aggregationResults.getMappedResults();
        log.info("templateList All:{}", JSON.toJSONString(templateList));
        return templateList;
    }

到了这里,关于【MongoDB】--MongoDB聚合Aggregation的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MongoDB聚合:$bucketAuto

    按照指定的表达式对输入文档进行分类后放入指定数字的桶中,跟 $bucket 不太一样, $bucketAuto 可以指定分组的数量(颗粒度), $bucketAuto 会根据 groupBy 的值和颗粒度自动生成桶的边界。 groupBy 表达式,对文档进行分组的表达式。若指定字段路径,需要在字段名前加上美元符

    2024年01月21日
    浏览(33)
  • MongoDB聚合:$listLocalSessions

    聚合管道阶段:$listLocalSessions 可以列出 mongod 或 mongos 实例缓存在内存中的会话。 $listLocalSessionsstage 阶段可以接受一个文档,其内容如下: 字段 含义 { } 如果运行时有访问控制,则返回当前已验证用户的所有会话,否则返回所有会话。 { users: [ { user: user, db: db }, ... ] } 返回指

    2024年01月18日
    浏览(30)
  • MongoDB聚合操作

    提示:以下是本篇文章正文内容,MongoDB 系列学习将会持续更新 单一作用聚合 :提供了对常见聚合过程的简单访问,操作都从单个集合聚合文档。 函数 描述 db.collection.estimatedDocumentCount() 忽略查询条件,返回集合或视图中所有文档的计数 db.collection.count() 返回与find()集合或视

    2024年02月03日
    浏览(33)
  • MongoDB聚合:$indexStats

    返回有关集合中每个索引使用情况的统计信息。如果运行时有访问控制,请至少以 clusterMonitor 角色的用户身份进行验证。 对于每个索引,返回文件包括以下字段: 字段 含义 name 索引名称 key 索引规格 host mongod 进程的主机名和端口。 accesses 使用索引的统计:ops 是使用索引的

    2024年01月18日
    浏览(37)
  • MongoDB聚合:$project

    $project 聚合阶段可将输入文档根据请求的字段输出到管道的下个阶段,输出的字段可以是输入文档中的字段,也可以是新的计算字段。 $project 聚合接受一个文档参数,可以指定包含的字段,抑制 _id 字段,添加新的字段以及重置已有字段的值等。亦或者,也可以指定排除的字

    2024年02月20日
    浏览(24)
  • MongoDB聚合:$unset

    使用 $unset 阶段可移除文档中的某些字段。从版本4.2开始支持。 移除单个字段,可以直接指定要移除的字段名: 移除多个字段,可以指定一个要移除字段名的数组: u n s e t 和 unset和 u n se t 和 project 对于移除字段, $unset 相当于是 $project 的别名: 内嵌字段 要移除或排除内嵌

    2024年02月19日
    浏览(34)
  • MongoDB聚合:$documents

    $documents 阶段可以根据输入值返回字面意义的文档。 $documents 接受可解析为对象数组的任何有效表达式,包括: 系统变量,如 $$NOW 或 $$SEARCH_META $let 表达式 $lookup 表达式作用域中的变量 没有指向当前文档的表达式(如 $myField 或 $$ROOT )将导致错误。 测试管道阶段 下面例子为

    2024年01月22日
    浏览(44)
  • MongoDB聚合:$densify

    $densify 阶段可以为文档序列中字段缺失的某些值创建新文档。其主要的用途有: 补齐时间序列数据。 为分组数据添加缺失值。 为指定的值范围填充数据。 $densify 阶段的语法: $densify 阶段的参数主要有以下字段: field 必选字段,要填充的字段,字段的值必须是数值或日期类

    2024年02月20日
    浏览(27)
  • MongoDB聚合:$set

    聚合 $set 阶段可以为文档添加新的字段。 $set 输出的文档包含输入文档中的所有现有字段和新添加的字段。 $set 是 $addFields 的别名,从MongoDB4.2开始支持。 $set 和 $addFields 等价于 $project 阶段,这两个阶段都等同于 $project 阶段,后者明确指定输入文档中的所有现有字段并添加新

    2024年01月18日
    浏览(33)
  • [Mongodb 5.0]聚合操作

     本文对应Aggregation Operations — MongoDB Manual    正文 此章节主要介绍了Aggregation Pipeline,其实就是将若干个聚合操作放在管道中进行执行,每一个聚合操作的结果作为下一个聚合操作的输入,每个聚合指令被称为一个stage。 在正式开始学习聚合操作前,请先按照下面的方式在你

    2024年02月12日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包