【MongoDB】--MongoDB聚合Aggregation

目录

  • 一、前言
  • 二、聚合管道操作
    • 2.1、实际案例1
      • (1)、案例--根据学生no,找到对应班级名称
      • (2)、案例--这个班级有哪些学生和哪些老师在任课
    • 2.2、实际案例2
      • (1)、案例--主表和关联表都有条件限制,且分页返回

一、前言

聚合操作组值来自多个文档,可以对分组数据执行各种操作以返回单个结果。聚合操作包含三类:单一作用聚合、聚合管道、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)、案例–主表和关联表都有条件限制,且分页返回

由于这里的查询要求分页,那么只能对要分页的主表进行返回。

  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对应主表的idAggregation.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;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/16069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【高级数据结构】线段树

目录 最大数&#xff08;单点修改&#xff0c;区间查询&#xff09; 线段树1&#xff08;区间修改&#xff0c;区间查询&#xff09; 最大数&#xff08;单点修改&#xff0c;区间查询&#xff09; 洛谷&#xff1a;最大数https://www.luogu.com.cn/problem/P1198 题目描述 …

springboot和springcloud的联系与区别

什么是springboot&#xff1f; Spring Boot是一个用于简化Spring应用程序开发的框架。它提供了一种约定优于配置的方式&#xff0c;通过自动配置和快速开发能力&#xff0c;可以快速搭建独立运行、生产级别的Spring应用程序。 在传统的Spring应用程序开发中&#xff0c;需要手…

网络防御之VPN

配置IKE 第一阶段 [r1]ike proposal 1 [r1-ike-proposal-1]encryption-algorithm aes-cbc-128 [r1-ike-proposal-1]authentication-algorithm sha1 [r1-ike-proposal-1]dh group2 [r1-ike-proposal-1]authentication-method pre-share[r1]ike peer aaa v1 [r1-ike-peer-aaa…

c# winform 子窗体关闭时主窗体执行指令

按下一个按钮打开子窗体&#xff0c;点 x 关闭子窗体后主窗体自动执行某些指令。例如刷新窗体&#xff0c;加载数据等。 点 x 关闭子窗体后将会执行"刷新父窗体2"下面的内容&#xff0c;其他的没试。 Config readConfigTest new Config();//new一个子窗体并打开 re…

面向对象中的多态性

一、权限修饰符 public, 缺省&#xff0c; protected&#xff0c;private 二、this和super关键字 this:表示当前对象 super:表示父类声明的成员 原则&#xff1a;遵循就近原则和追根溯源原则。 三、Object类 java.lang.Object类是所有java类的超类&#xff0c;即所有的J…

【算法心得】二维dp的状态转移狂练

LCS&#xff1a; LCS变式&#xff1a;使两个字符串变成一样的&#xff0c;删除的和最小 https://leetcode.cn/problems/minimum-ascii-delete-sum-for-two-strings/ 建表 m ∗ n m*n m∗n or ( m 1 ) ∗ ( n 1 ) (m1)*(n1) (m1)∗(n1)&#xff1f; 感觉 ( m 1 ) ∗ ( n …

git从主仓库同步到fork仓库

git从主仓库同步到fork仓库 1. fork远程仓库到本地仓库2. 将远程仓库添加到本地3. 更新本地项目主库地址4. 将远程仓库更新到本地仓库5. 将本地仓库合到远程分支 1. fork远程仓库到本地仓库 方式一&#xff1a;通过git命令 git clone fork库地址方式二&#xff1a;通过git页面…

VBA技术资料MF36:VBA_在Excel中排序

【分享成果&#xff0c;随喜正能量】一个人的气质&#xff0c;并不在容颜和身材&#xff0c;而是所经历过的往事&#xff0c;是内在留下的印迹&#xff0c;令人深沉而安谧。所以&#xff0c;优雅是一种阅历的凝聚&#xff1b;淡然是一段人生的沉淀。时间会让一颗灵魂&#xff0…

Dart语言学习笔记(一)

1、命名规则 /*** 1&#xff09;.变量名称必须包含数字&#xff0c;字母&#xff0c;下划线&#xff08;_&#xff09;&#xff0c;和美元符号&#xff08;$&#xff09;组成 2&#xff09;.标识符的开头不能是数字开头3&#xff09;.标识符不能使用关键字和保留字4&#xff…

jMeter使用随记

参数化BodyData 先制作参数文件 再设置一个csv data set config 最后在body data里面写上参数${xxxxx}

实用调试技巧(1)

什么是bug&#xff1f;调试是什么&#xff1f;有多重要&#xff1f;debug和release的介绍。windows环境调试介绍。一些调试的实例。如何写出好&#xff08;易于调试&#xff09;的代码。编程常见的错误。 什么是Bug 我们在写代码的时候遇到的一些问题而导致程序出问题的就是Bu…

vue使用Clodop插件打印

一、前往lodop官网&#xff0c;下载插件&#xff0c;http://www.lodop.net/index.html 这里下载的window64位的&#xff0c;将插件安装好&#xff0c;运行&#xff0c;会看到 点击‘去了解C-Lodop>>’,会跳转至使用说明页面&#xff0c;在这个页面里&#xff0c;可以打印…

华为OD机考真题--数大雁--带答案

2023华为OD统一考试&#xff08;AB卷&#xff09;题库清单-带答案&#xff08;持续更新&#xff09;or2023年华为OD真题机考题库大全-带答案&#xff08;持续更新&#xff09; 题目描述: 一群大雁往南飞&#xff0c;给定一个字符串记录地面上的游客听到的大雁叫声&#xff0c;请…

在登录界面中设置登录框、多选项和按钮(HTML和CSS)

登录框&#xff08;Input框&#xff09;的样式&#xff1a; /* 设置输入框的宽度和高度 */ input[type"text"], input[type"password"] {width: 200px;height: 30px; }/* 设置输入框的边框样式、颜色和圆角 */ input[type"text"], input[type&q…

使用maven容器打包java项目

docker run --rm -v /path/to/your/microservice:/app -w /app maven:latest mvn clean package 解释一下上面的命令&#xff1a; docker run&#xff1a;运行Docker容器。--rm&#xff1a;在容器运行结束后自动删除容器&#xff0c;避免堆积未使用的容器。-v /path/to/you…

使用springboot aop记录接口请求的参数及响应

概述 使用aop做日志记录&#xff0c;记录输入的参数名及参数值&#xff0c;并且记录接口响应结果。 切面类 package com.zou.metabox.common.aspect;import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import o…

【RabbitMQ】之消息的可靠性方案

目录 一、数据丢失场景二、数据可靠性方案 1、生产者丢失消息解决方案2、MQ 队列丢失消息解决方案3、消费者丢失消息解决方案 一、数据丢失场景 MQ 消息数据完整的链路为&#xff1a;从 Producer 发送消息到 RabbitMQ 服务器中&#xff0c;再由 Broker 服务的 Exchange 根据…

深度学习实践——卷积神经网络实践:裂缝识别

深度学习实践——卷积神经网络实践&#xff1a;裂缝识别 系列实验 深度学习实践——卷积神经网络实践&#xff1a;裂缝识别 深度学习实践——循环神经网络实践 深度学习实践——模型部署优化实践 深度学习实践——模型推理优化练习 深度学习实践——卷积神经网络实践&#xff…

简单认识NoSQL的Redis配置与优化

文章目录 一、关系型数据库与非关系型数据库1、关系型数据库&#xff1a;2、非关系型数据库3、关系型数据库和非关系型数据库区别&#xff1a;4、非关系型数据库应用场景 二.Redis1、简介2、优点&#xff1a;3、Redis为什么这么快&#xff1f; 三、Redis 安装部署1、安装配置2、…

解析RocketMQ:高性能分布式消息队列的原理与应用

解析RocketMQ&#xff1a;高性能分布式消息队列的原理与应用 引言 什么是消息队列 消息队列是一种消息传递机制&#xff0c;用于在应用程序和系统之间传递消息&#xff0c;实现解耦和异步通信。它通过将消息发送到一个中间代理&#xff08;消息队列&#xff09;&#xff0c;…