【Mongodb-04】Mongodb聚合管道操作基本功能

news2024/11/15 11:55:21

Mongodb系列整体栏目


内容链接地址
【一】Mongodb亿级数据性能测试和压测https://zhenghuisheng.blog.csdn.net/article/details/139505973
【二】springboot整合Mongodb(详解)https://zhenghuisheng.blog.csdn.net/article/details/139704356
【三】亿级数据从mysql迁移到mongodb辛酸历程https://zhenghuisheng.blog.csdn.net/article/details/140302930
【四】Mongodb聚合管道操作基本功能https://zhenghuisheng.blog.csdn.net/article/details/140402214

mongodb聚合操作基本功能

  • 一,mongodb聚合操作基本功能
      • 1,单一聚合
      • 2,聚合管道 + 聚合操作符
        • 2.1,Count
        • 2.2,SUM
        • 2.3,Group By
        • 2.4,分组+排序
        • 2.5,多字段分组+时间格式化
        • 2.6,Group By + Having
        • 2.7,Where
        • 2.8,子查询
        • 2.9,分页
        • 2.10,连表查询

一,mongodb聚合操作基本功能

在mysql中,允许一些匹配,分组,排序,分页,求和以及多表之间的连表操作,在mongodb中,这些操作也是可以实现的,内部就是通过聚合操作实现。在mongodb中,聚合操作主要有三大类操作,分别是: 单一作用聚合、聚合管道、MapReduce ,在mongodb5.0开始,mapReduce被废弃,因为能通过MapReduce实现的功能,都可以通过这个聚合管道实现,并且聚合管道的效率还远高于MapReduce,因此本文主要是了解单一管道和聚合管道。

在了解聚合管道之前,可以先通过官方文档的教程以及如何使用:mongodb聚合管道的使用

管道的模型如下,其设计理念就是通过流水线的模式,每一个步骤处理一个操作,,每一个步骤处理完的结果传给下一个步骤,最后将结果给返回

请添加图片描述

在官网中,给了一个 sql-聚合 的映射图标,通过sql中的语法和者术语来更加清楚的了解 聚合操作的概念和使用

请添加图片描述

1,单一聚合

假设此时有一张orders的订单集合,类似于mysql中的orders订单表,在mongodb中对这些单一聚合提供了简单访问,如以下获取文档的总个数,去重等,纯原生的方式实现数据的获取,在性能上没有聚合管道的效率高

db.orders.estimatedDocumentCount(),  
db.orders.countDocument(),
db.orders.distinct()

2,聚合管道 + 聚合操作符

在官方文档中给了很多的聚合阶段的方式,接下来主要是结合官方提供的映射图标的文档,来理解mongodb中常用的一些聚合方式。在讲解聚合管道之前,先提供一些mongodb内部的一些操作符,类似于mysql的一些聚合函数,如比较操作符,日期操作符,算术表达式操作符等等。通过管道再结合对应的操作符,来实现对文档的查询,从而使得mongodb可以和关系型数据库一样的操作流程,并通过json的数据格式,让整个查询更加的灵活

在这里插入图片描述

2.1,Count

在mysql中,计算一张表的数据有多少条,可以直接使用 count(*) 命令

select count(*) as count from orders

在mongodb中聚合管道的操作命令如下,_id为空就是表示不根据某个字段进行分组,即所有文档在同一个组里面,里面的 {$sum:1} 表示的是一个累计计数器的效果,表示查询出文档的条数,这里的每有一条文档那么这个计数器就会加1。比如查询出来是100条,那么count的值就是100,和上面mysql的as count的操作是一样的

db.orders.aggregate([
    {
        $group:{
    		_id:null,
            count:{$sum:1}
        }
    }
])
2.2,SUM

对于mysql的求和统计操作,一般都是通过sum聚合函数实现,如查看订单表中的总价格的和

SELECT SUM(price) AS total FROM orders

在moogodb中的实现也可以如下,管道结合 $sum 操作符实现,这里和上面的一样,只是在sum求和时携带的参数不一样,上面的值设置的是1,下面的值设置的是每条文档中具体的某个字段的值,因此可以统计出所有订单的汇总价格

db.orders.aggregate([
 	{
    	$group:{
    		_id:null,
    		total:{$sum:"$price"}
    	}
    }   
])
2.3,Group By

在上面虽然也用了group by,但是在 _id 那个字段并没有设置对应文档中的字段,在实际情况看到会有根据某个字段先分组早再求和的情况,如根据用户id进行分组再进行求和

select user_id,sum(price) as total from orders group by user_id

结合上面的1,2两点,可以得知上面的mysql的效果实现如下,让_id 字段设置成要分组的字段即可

db.orders.aggregate([
    {
        $group:{
            _id:"$user_id",
            total:{$sum:"price"}
        }
    }
])
2.4,分组+排序

在订单表中,要查出每一个用户下单花费的总金额,并通过从大到小的方式进行排序

select user_id,sum(price) as total from orders group by user_id order by total

mongodb的实现如下,这里需要两个聚合操作,将上一个聚合操作的结果给下一个聚合操作,在sort聚合函数中,1表示升序,2表示降序

db.orders.aggregate([
    {
    	$group:{
    		_id:"$user_id",
    		total:{$sum,"$price"}
    	}
    },
    {
    	$sort:{total:1}
    }
])
2.5,多字段分组+时间格式化

就是需要通过user_id+每天的进行分组,统计每个用户每天消费了多少

select 
    user_id,date_format(created_at,'%y-%m-%d') as order_date,sum(price)
from 
    orders
group by 
    user_id,date_formate(created_at,'%-y-%m-%d')    

mongodb的聚合操作如下,如果有多个分组字段,那么就在 _id 对象中设置多个参数,并且按照从上往下的顺序设置,使用日期表达式操作符将时间进行格式化

db.orders.aggregate([
    {
        $group:{
            _id:{
    			user_id:"$user_id",
               	order_date: { 
    				$dateToString: {
              			format: "%Y-%m-%d",
              			date: "$created_at"
           			}
    			}
    		},
    		total:{$sum:"price"}
        }
    }
])
2.6,Group By + Having

比如返回用户消费大于1000的用户信息,mysql的语法如下

select user_id,sum(price) as total from orders group by user_id having total > 1000

使用mongodb聚合操作的语法如下,通过match聚合命令匹配实现,并且结合gt的比较运算符进行数据的过滤,最后将对应的文档返回

db.orders.aggregate([
    {
        $group:{
            _id:"user_id",
          	total:{$sum:"$price"}
        }
    },
    {
        $match:{
            total:{count:{$gt:1000}}
        }
    }
])
2.7,Where

比如返回订单表中商品id为10001的商品,并且差每个人花费的总金额,按降序排序

select user_id,sum(price)as total from orders where product_id = 10001 group by user_id order by total

使用mongodb的聚合操作的语法如下,期语法罗伊和mysql的一样,先过滤,再分组,再排序

db.orders.aggregate([
    {
        $match:{
            product_id:10001
        },
        $group:{
    		_id:"$user_id",
    		total:{$sum:"$price"}
    	},
        {
    		$sort:{total:1}
    	}
    }
])
2.8,子查询

比如查询一个简单的,查询订单表中总共有多少用户下单(用户去重)

SELECT
    COUNT(*)
FROM 
    (
        SELECT user_id FROM orders GROUP BY user_id
    ) t

通过mongodb举个查询的语法如下,只需要通过两个group就能实现,在第二个group中将id值设置为null

db.orders.aggregate([
    {
        $group:{
    		_id:"$user_id",
    		total:{$sum:"$price"}
    	}
    },
    {
         $group:{
    		_id:null,
    		count: { $sum: 1 }
    	}
    }
])
2.9,分页

在mysql中,分页查询直接通过limit即可,如查询订单表中商品id为10001的花费最多的钱10名的用户

select
	user_id,sum(price) as total
from orders
where product_id = 10001
group by 
	user_id 
order by total desc limit 10

在mongodb的聚合管道中,其实现方式也比较简单,只需要多聚合几个条件即可,先执行where条件的管道,然后分组管道,排序管道,分页管道,最终将数据返回,通过数据库层面实现数据的过滤和查询,从而减少网络io传输

db.orders.aggregate([
    {
        $match:{product_id,10001},
    },
    {
        $group:{
            _id:"$user_id",
            total:{$sum:"$price"}
        }
    },
    {
        $sort:{total:-1}
    },
    {
        $limit:10
    }
])
2.10,连表查询

在mysql中,查询商品id为10001的花费最多的钱10名的用户的用户名

select
	u.name,order.user_id,sum(order.price) as total
from orders order
left join user u on u.id = order.user_id
where order.product_id = 10001
group by 
	order.user_id 
order by total desc limit 10

通过mongodb聚合渠道的方式如下,通过$lookup 关键字来实现联表,from表示需要连接的那张表,localField表示主表中需要关联的字段,foreignField表示需要关联的那张表中要关联的字段,最活通过一个 unwind 关键字将数组的值展开,让每一个订单表中查询出来的数据对应一个用户信息,最后再通过增加一个分组,排序和分页的聚合操作

db.orders.aggregate([
    { $match: { product_id: 10001 } },  // 筛选出 product_id 为 10001 的订单
    { $lookup: {                       // 左外连接用户表
        from: "users",                 // 'users' 集合(假设用户集合名称为 users)
        localField: "user_id",         // orders 集合中连接键
        foreignField: "id",            // users 集合中连接键
        as: "user_info"                // 查询结果的新字段名
    }},
    { $unwind: "$user_info" },         // 展开连接结果,使每个订单对应一个用户信息
    { $group: {                        // 分组操作
        _id: "$user_id",               // 根据 user_id 分组
        name: { $first: "$user_info.name" },  // 从用户信息中获取名字
        total: { $sum: "$price" }              // 计算总金额
    }},
    { $sort: { total: -1 } },          // 按 total 降序排序
    { $limit: 10 }                     // 限制结果为前 10 条
]);

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

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

相关文章

【Mac】App Cleaner Uninstaller(Mac应用清理和卸载)及同类型软件介绍

今天给大家介绍的软件是App Cleaner & Uninstaller,这是一款mac应用清理和卸载软件,还会介绍同类型的其他几款软件,大家可以选择自己适合的来使用。 App Cleaner & Uninstaller软件介绍 App Cleaner & Uninstaller 是一款专门用…

《知识点扫盲 · 学会 WebService》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…

《斯科特·凯尔比的风光摄影手册》读书笔记

写在前面 《斯科特凯尔比的风光摄影手册》读书笔记整理没有全部读完,选择了感兴趣的章节理解不足小伙伴帮忙指正 😃,生活加油 99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,…

NLP之词的重要性

文章目录 何为重要词TF*IDFTF*IDF其他版本TFIDF 算法特点TF*IDF的优势TF*IDF劣势 TF*IDF的应用搜索引擎文本摘要文本相似度计算 上一篇文章介绍了新词的发现,用内部凝固度和左右熵来发现新词。这时候机器对一篇文章有了对词的一定理解,这时我们让机器上升…

云服务器重置密码后,xshell远程连接不上,重新启用密码登录方式

云服务器重置密码后 ,xshell连接出现不能使用密码登录 解决方案:以下来自阿里云重新启用密码登录方式帮助文档 为轻量应用服务器创建密钥且重启服务器使密钥生效后,服务器会自动禁止使用root用户及密码登录。如果您需要重新启用密码登录方式&…

【python】基于决策树的语音识别

目录 引言 决策树的主要特点 决策树的构建过程 决策树的应用 数据集 代码实现 引言 决策树(Decision Tree)是一种常用的分类与回归方法,其中最为人所知的是其在分类问题上的应用。决策树模型呈树形结构,其中每个内部节点表…

centos7|Linux操作系统|编译最新的OpenSSL-3.3,制作rpm安装包

一、 为什么需要编译rpm包 通常,我们需要安装某个软件,尤其是在centos7这样的操作系统,一般是通过yum包管理器来安装软件,yum的作用是管理rpm包的依赖关系,自动的处理rpm包的安装顺序,安装依赖等的相关问…

【数智化案例展】沃太能源——MES系统建设引领智能制造新篇章

‍ 联想集团案例 本项目案例由联想集团投递并参与数据猿与上海大数据联盟联合推出的《2024中国数智化转型升级创新服务企业》榜单/奖项评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 沃太能源股份有限公司,一家在储能产品及智慧能源管理方案领域享有盛誉的…

对B-树的理解

目录 前言-为什么要使用B-树?B-树概念 前言-为什么要使用B-树? 首先,我们正常的搜索都有一下方式: 搜索二叉树,极端场景下会退化,类似于单支,此时的效率变成了O(N);为了解决1的问题…

基于微信小程序的音乐播放平台

基于微信小程序的音乐播放平台 音乐播放小程序项目简介技术栈功能模块项目流程系统E-R图项目页面 音乐播放小程序 项目简介 微信音乐小程序旨在提供一个简洁高效的音乐播放平台,用户可以方便地搜索、播放和收藏自己喜欢的音乐。整个项目采用前后端分离的架构&…

Rust 测试的组织结构

测试的组织结构 本章一开始就提到,测试是一个复杂的概念,而且不同的开发者也采用不同的技术和组织。Rust 社区倾向于根据测试的两个主要分类来考虑问题:单元测试(unit tests)与 集成测试(integration test…

基于3D感知的端到端具身操作论文导读

DexIL:面向双臂灵巧手柔性操作的端到端具身执行模型 模型架构 输入:   观测Ot: RGB点云,使用PointNet进行编码;   状态St: 双臂末端7x2Dof位姿16x2灵巧手关节位置,只进行归一化,无编码&am…

在word中删除endnote参考文献之间的空行

如图,在References中,每个文献之间都有空行。不建议手动删除。打开Endnote。 打开style manager 删除layout中的换行符。保存,在word中更新参考文献即可。

InjectFix 热更新解决方案

简介 今天来谈一谈,项目种的客户端热更新解决方案。InjectFix是腾讯xlua团队出品的一种用于Unity中C#代码热更新热修复的解决方案。支持Unity全系列,全平台。与xlua的思路类似,InjectFix解决的痛点主要在于Unity中C#代码写的逻辑在发包之后无…

复杂设备操作流程3D数字化全景展示好处多

传统的纸质说明书,尽管承载着产品的使用指南,但其图文平面的表现形式往往限制了表现力和说明力。对于简单产品,用户或许能摸索使用;但对于复杂产品,即使拥有详实的说明书,也可能因理解困难而导致使用障碍。现在&#x…

【工具使用】adb下载和配置

【工具使用】adb下载和配置 一,简介二,操作步骤2.1 Bing搜索adb2.2 下载adb工具2.3 添加路径到环境变量 三,效果验证 一,简介 本文主要介绍如何下载adb并安装使用,供参考。 此时打开cmd,输入adb 会提示&am…

<数据集>猫狗识别数据集<目标检测>

数据集格式:VOCYOLO格式 图片数量:3686张 标注数量(xml文件个数):3686 标注数量(txt文件个数):3686 标注类别数:2 标注类别名称:[cat, dog] 序号类别名称图片数框数1cat118811892dog24982498 使用标…

计算机网络复习笔记【面向考纲整理】

计算机网络复习笔记 一、计算机网络体系结构(一)计算机网络的概念、分类、组成与功能1.计算机网络的概念、组成与功能1.1计算机网络的概念1.2计算机网络的组成1.3计算机网络的功能 2.计算机网络的分类3.计算机网络的标准化工作及相关知识 (二…

主机安全-进程、命令攻击与检测

目录 概述反弹shell原理nc/dev/xxx反弹shell下载不落地反弹Shell各种语言反弹shell linux提权sudosuid提权mysql提权 Dnslog参考 概述 本文更新通过在主机(不含容器)上直接执行命令或启动进程来攻击的场景。检测方面以字节跳动的开源HIDS elkeid举例。每…

E9.【C语言】练习:模拟用户登录界面,最多输入三次密码以及strcmp函数的讲解

思路&#xff1a;分两个环节 1.输入密码&#xff0c;存储在数组里 2.密码验证&#xff08;尝试次数不超过3次&#xff09; #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> int main() {char password[20] { 0 };int i 0;for ( i …