当前位置: 首页 > article >正文

MongoDB Shell 基本命令(三)聚合管道

  1. 管道含义
    类似Linux中的管道,前一个命令的输出作为后一个命令的输入。
    在这里插入图片描述

  2. 显示网络连接、路由表和网络接口统计信息

netstat -ano
-netstat:network statistics 网络统计
-a:显示所有连接和监听端口,包括所有活动的TCPUDP连接。
-n:以数字形式显示地址和端口号,而不是尝试解析为主机名和服务名称。
-o:显示与每个连接关联的进程ID(PID),这使得用户可以知道哪个进程正在使用特定的网络连接。

加上管道,查看与某个特定端口(27017)相关的连接,findstr相当于Linux中的grep,用于查找字符串的命令行工具。

netstat -ano | findstr :27017

在这里插入图片描述

“ESTABLISHED” 是 TCP 协议的一种状态,表示一条 TCP连接已经成功建立,并且可以开始数据通信。

加上管道,只查看LISTENING相关连接

netstat -ano | findstr :27017 | findstr :27017 | findstr LISTENING

在这里插入图片描述

所以,管道的含义就是:前一个命令的结果,作为后续命令的输入。我们可以在前面查询的基础上,整理过后,再进行查询。

select count(*) from tabname where ...;
select sum() from tabname group by ...;先分组再统计,相当于是多步操作
  1. count()和distinct()
use cqust;
//如果查询条件为空,查询文档记录数
db.students.count();//集合的文档总数

//统计女生/男生的数量
var 查询条件={gender:0};
db.students.count(查询条件);

//第二种写法
db.students.find(查询条件).count()//count(查询条件)等价于find(查询条件).count()

//select distinct major from tbname
//distinct,获取不重复的取值
//查询2022级有哪些专业
var 查询条件={grade:2022};
var 返回字段={_id:0,major:1,grde:1};
db.students.find(查询条件,返回字段);//有重复值

//格式:db.students.distinct(取值字段,查询条件)
db.students.distinct("major",查询条件);//返回数组

//2022级学生上了哪些课程
db.students.distinct("courses.course",{grade:2022});

//一共有哪些课程
db.students.distinct("courses.course");
  1. 聚合管道
  • 聚合是数据处理和分析的过程,对来自多个文档的数据进行计算、总结和分析,强调数据的汇总和计算。
  • 管道是一个结构,通过多个处理阶段(每个阶段可以执行不同类型的操作)来实现聚合的过程。
  • 分组操作用到聚合管道。
image-20241027155427833
  • $match:过滤输入文档,只有满足指定条件的文档会被传递到管道的下一个阶段。where(sql)
  • $group:将输入文档分组,并按指定的键对每个组编制汇总。可以计算总和、平均值等。
  • $sort:对输入文档进行排序。1、0升序和降序;
  • $project:重塑输入文档,选择需要的字段并可以添加计算字段。(字段名修改、增加字段)
  • limit和skip:用于限制返回的结果数量或跳过指定数量的文档。

第一阶段$match阶段按status字段过滤文档,并将status等于"A"的文档传递到下一阶段。

第二阶段$group阶段按cust_id字段将文档分组,以计算每个cust_id唯一值的金额总和。

$match 的含义- 功能: $match 阶段用于过滤集合中的文档,以保留所有符合指定条件的文档。它的作用类似于 SQL 中的 WHERE 子句。

  • 聚合管道格式
db.orders.aggregate([
    { $match: { status: "A" } },
    { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }
])
//var 步骤1={步骤操作符:操作文档}
//var 步骤数组=[步骤1,步骤2,步骤3,...]
//db.集合名.aggregate(步骤数组)
{$group:{_id:分组字段,聚合字段:{$统计操作:$值字段}}}
{$project:{field1:1,newfield2:$oldfield2}}
{$sort:{field1:1,field2:-1}}
{$limit},{$skip}
{$unwind:"$listfield"} 将数组中的元素分配到多行(拉平数组)
  • 筛选出选择分布式数据库原理与应用的学生信息
var 步骤1 = {$match:{"courses.course":"分布式数据库原理与应用"}};
var 步骤1 = {$match:{"courses.course":/分布式/}};//正则表达式,匹配包含”分布式“
var 步骤数组 = [步骤1];
db.students.aggregate(步骤数组);
  • 统计男女生人数 0女生 1男生
//select count(*) as 人数,gender from students group by gender
//group操作符,取值进行group by
var 步骤1 = {$group:{_id:"$gender",人数:{$sum:1}}};
var 步骤数组 = [步骤1];
db.students.aggregate(步骤数组);
  • 为了让刚才的结果更直观,用到project ,这个阶段在数据处理过程中起到了选择、重命名和计算字段的重要作用。
var 步骤1 = {$group:{_id:"$gender",人数:{$sum:1}}};
var 步骤2 = {$project:{性别:"$_id",人数:1,_id:0}};//1表示返回原来的人数
var 步骤数组 = [步骤1,步骤2];
db.students.aggregate(步骤数组);
  • 统计大数据专业男女生人数
var 步骤0={$match:{"major":"大数据"}};
var 步骤1={$group:{_id:"$gender",人数:{$sum:1}}}//$表示值,sum:1相当于是count
var 步骤2={$project:{性别:"$_id",人数:1,_id:0}}
var 步骤数组=[步骤0,步骤1,步骤2]
db.students.aggregate(步骤数组)
  • 统计2022级大数据专业1班男女生人数
//非分组做法,分别统计
db.students.count({major:"大数据",grade:2022,class:1,gender:0});//求出女生人数
db.students.count({major:"大数据",grade:2022,class:1,gender:1});//求出男生人数
//分组做法
var 先找出本班所有学生的记录 ={$match:{major:"大数据",grade:2022,class:1}};
var 计算男女生的数量={$group:{_id:"$gender",人数:{$sum:1}}};//相当于是求了count
db.students.aggregate([先找出本班所有学生的记录,计算男女生的数量]);
  • 统计2022级大数据专业1班男女体重和
//db.students.aggregate([{阶段1},{阶段2},{阶段3},...])
//db.students.aggregate([先找出本班所有学生的记录,然后分男女计算体重的和,整理结果]);
//统计2022级大数据专业1班男女体重和
//select sum(bodyweight) as 总体重, gender as 性别 
//from tbstudents 
//group by gender
//where major="大数据" and grade=2020 and class=1
var 先找出本班所有学生的记录 = {$match:{major:"大数据",grade:2022,class:1}};
var 然后分男女计算体重的和 = {$group:{_id:"$gender",总体重:{$sum:"$body.weight"}}};
var 整理结果 = {$project:{_id:0,"性别":"$_id",总体重:"$总体重","单位":"kg"}};
db.students.aggregate([先找出本班所有学生的记录,然后分男女计算体重的和,整理结果])
  • 加减乘除运算符号 a d d 、 add、 addsubstract、 m u l t i p l y 、 multiply、 multiplydivide
var 先找出本班所有学生的记录 = {$match:{major:"大数据",grade:2022,class:1}};
//var 然后分男女计算体重的和 ={$group:{_id:分组字段,聚合字段:{$统计操作:$值字段}};
var 然后分男女计算体重的和 = {$group:{_id:"$gender",总体重:{$sum:"$body.weight"}}};
//var 整理结果 = {$project:{_id:0,"性别":"$_id",总体重:"$总体重","单位":"kg"}};
//var 整理结果 = {$project:{_id:0,"性别":"$_id",总体重:{$add:["$总体重",1000]},"单位":"kg"}};//通过$add增加1000
//var 整理结果 = {$project:{_id:0,"性别":"$_id",总体重:{$subtract:["$总体重",2000]},"单位":"kg"}};//通过$add减少2000
var 整理结果 = {$project:{_id:0,"性别":"$_id",总体重:{$multiply:["$总体重",2]},"单位":"kg"}};//通过$add减少2000
//var 整理结果 = {$project:{_id:0,"性别":"$_id",总体重:{$divide:["$总体重",1000]},"单位":"t"}};//通过$divide将体重从kg转换为吨 
db.students.aggregate([先找出本班所有学生的记录,然后分男女计算体重的和,整理结果]);
  • 统计各科课程的平均分
// "courses": [
//        {
//            "course": "结构化数据存储与应用",
//            "credit": 2,
//            "score": 67
//        }
//    ]

//var 分组统计 = {$group:{_id:分组字段,聚合字段:{$统计操作:$值字段}}}
var 分组统计 = {$group:{_id:"$courses.course",平均分:{$avg:"$courses.score"}}};
db.students.aggregate([分组统计]);//直接这样查询有问题,对于数组\数组字段,无法直接分组统计

二维------>一维(unwind) ;

{ u n w i n d : " unwind:" unwind:"listfield"} 将列表中的元素分配到多行(拉平数组)

正确写法

//需要先将数组拉平,也就是说将数组中的值拆出来与其他字段连接
// {A,B:[1,2]} => {A,B:1} {A,B:2}
var 平摊数组 = {$unwind:"$courses"};
var 分组统计 = {$group:{_id:"$courses.course", 平均分:{$avg:"$courses.score"}}};
//db.students.aggregate([平摊数组]);//此时可以看出,数组已经被拉开了
db.students.aggregate([平摊数组,分组统计]);
  • 在上一步基础上,利用 s o r t 和 sort和 sortlimit返回前3结果
var 平摊数组 = {$unwind:"$courses"};
var 分组统计 = {$group:{_id:"$courses.course", 平均分:{$avg:"$courses.score"}}};
var 排序 = {$sort:{平均分:-1}};
var 返回前3结果 = { $limit : 3 }
db.students.aggregate([平摊数组,分组统计,排序,返回前3结果]);
  • 在上一步基础上,统计平均分大于74.5分的课程
//select avg(score) 平均分,course from tbstudents group by course having 平均分>=74.5
var 平摊数组 = {$unwind:"$courses"};
var 分组统计 = {$group:{_id:"$courses.course", 平均分:{$avg:"$courses.score"}}};
var 结果筛选 = {$match:{"平均分":{$gte:74.5}}}
db.students.aggregate([平摊数组,分组统计,结果筛选])// 方法用于在集合上执行一系列的聚合操作。
  • 统计分布式数据库原理与应用的平均分
var 平摊数组 = {$unwind:"$courses"};
var 分组统计 = {$group:{_id:"$courses.course", 平均分:{$avg:"$courses.score"}}};
var 结果筛选 = {$match:{"_id":/分布式/}}//非courses.course中,$match 是一个筛选操作符,用于过滤文档
//使用了正则表达式来匹配 _id 字段包含“分布式”字符串的文档。
var 整理结果 = {$project:{"course":"$_id","avgscore":{$round:["$平均分",2]},_id:0}}//$project 用于选择和重命名文档中的字段。指定将 _id 字段重命名为 course,平均分 字段重命名为 avgscore,并且排除 _id 字段在输出结果中显示(_id: 0 表示不显示 _id 字段)。{$round:["$平均分",2]}四舍五入,保留两位小数
db.students.aggregate([平摊数组,分组统计,结果筛选,整理结果])
  • 统计分布式数据库课程的平均分,要求保留两位小数
//统计分布式数据库课程的平均分,要求保留两位小数
var 平摊数组 = {$unwind:"$courses"};
var 分组统计 = {$group:{_id:"$courses.course", 平均分:{$avg:"$courses.score"}}};
var 整理结果 = {$project:{"course":"$_id","avgscore":{$round:["$平均分",2]},_id:0}}//$project 用于选择和重命名文档中的字段。指定将 _id 字段重命名为 course,平均分 字段重命名为 avgscore,并且排除 _id 字段在输出结果中显示(_id: 0 表示不显示 _id 字段)。{$round:["$平均分",2]}四舍五入,保留两位小数
db.students.aggregate([平摊数组,分组统计,结果筛选,整理结果])
  • 统计各班级(专业\年级\班级)分布式数据库课程的平均分
//方法一:直接连接
var 拉平数组 = {$unwind:"$courses"};
var 查找课程 = {$match:{"courses.course":/分布式/}};
//_id是一个组合字段,包括专业、年级、班级信息
var 按班级统计平均分 = {$group:{_id:{专业:"$major",年级:"$grade",班级:"$class"},平均分:{$avg:"$courses.score"}}}
var 整理结果 = {$project:{专业:"$_id.专业",年级:"$_id.年级",班级:"$_id.班级",平均分:{$round:["$平均分",2]},_id:0}};
db.students.aggregate([拉平数组,查找课程,按班级统计平均分,整理结果]);

//方法二:利用$concat连接,$tostring强制转换
var 拉平数组 = {$unwind:"$courses"};
var 查找课程 = {$match:{"courses.course":/分布式/}};
//_id是一个组合字段,包括专业、年级、班级信息
var 按班级统计平均分 = {$group:{_id:{"行政班级":{$concat:["$major",{$toString:"$grade"},"-0",{$toString:"$class"}]}},平均分:{$avg:"$courses.score"}}};
var 整理结果 = {$project:{"行政班级":"$_id.行政班级",平均分:{$round:["$平均分",2]},_id:0}};
var 排序 = {$sort:{"行政班级":1}};//按照行政班级升序
db.students.aggregate([拉平数组,查找课程,按班级统计平均分,整理结果,排序]);
  • 按专业求女生平均身高低于170的学生,并排序($sort)
/* 
SQL: select AVG(height) as avgHeight, major as _id 
     from students 
	 where gender=0
	 group by major
	 having avgHeight<=170
	 sorted by avgHeight DESC
*/	
db.getCollection("students").aggregate([
 //第一步,查数据
 {$match:{gender:0}}
 //第二步,限制返回字段
 ,{$project:{_id:0,major:1, grade:1, class:1, height:"$body.height"}}
 //第三步,分组求平均值
 // _id: group by的字段, 字段名要加$符号前缀,表示是一个字段名
 // avgHeight: 新生成的平均值字段名
 // $avg: 平均值操作符,它的值为要求平均值的字段名,注意加$前缀
 ,{$group:{_id:"$major", avgHeight:{$avg:"$height"}}}
 //第四步,筛选聚合结果
 ,{$match:{avgHeight:{$lte:170}}}
 //第五步,排序,按照avgHeight的值从大到小排序, -1: DESC, 1:ASC
 ,{$sort:{avgHeight:-1}}
 //,{$limit:1}  //取结果中最接近170的值
])
  • 课堂练习
1.统计各课程的平均分,并返回倒数第一名的结果
2.统计本专业分布式数据库课程的平均分,并且保留两位小数

http://www.kler.cn/a/378713.html

相关文章:

  • 考研要求掌握的C语言程度(插入排序)
  • angular实现list列表和翻页效果
  • 运维工具之docker入门
  • aws(学习笔记第十课) 对AWS的EBS如何备份(snapshot)以及使用snapshot恢复数据,AWS实例存储
  • crc16 with word byte--查表法
  • 本地部署bert-base-chinese模型交互式问答,gradio
  • 银河麒麟v10 xrdp安装
  • Tomcat 和 Docker部署Java项目的区别
  • uniapp使用中小问题及解决方法集合
  • ARM base instruction -- bfxil
  • 第五篇: 使用Python和BigQuery进行电商数据分析与可视化
  • 【bug解决】 g++版本过低,与pytorch不匹配
  • 下载安装COPT+如何在jupyter中使用(安装心得,windows,最新7.2版本)
  • postgresql增量备份系列一
  • TensorRT-LLM的k8s弹性伸缩部署方案
  • 数据转换 | Matlab基于SP符号递归图(Symbolic recurrence plots)一维数据转二维图像方法
  • Unity XR Interaction Toolkit 开发教程(4)XR Origin:追踪参考系与相机高度【3.0以上版本】
  • 三层交换技术,eNSP实验讲解
  • 【大模型开发指南】llamaindex配置deepseek、jina embedding及chromadb实现本地RAG及知识库(win系统、CPU适配)
  • Redis系列---数据管理
  • git入门教程8:git高级分支管理
  • YOLO11论文 | 重要性能衡量指标、训练结果评价及分析及影响mAP的因素【发论文关注的指标】
  • Docker Swarm集群配置与使用
  • 基于知识中台的智能法律咨询服务:革新法律服务的新篇章
  • sicp每日一题[2.65]
  • 【D3.js in Action 3 精译_039】4.3 D3 面积图的绘制方法及其边界标签的添加