mongodb的聚合操作
在mongodb中有时候我们需要对数据进行分析操作,比如一些统计操作,这个时候简单的查询操作(find)就搞不定这些需求,因此就需要使用 聚合框架(aggregation) 来完成。在mongodb中提供了三种方式来完成聚合操作。aggregation pipeline map-reduce function, and single purpose aggregation methods,本篇文章主要讲解aggregation pipeline(聚合管道)的使用。
Aggregation Pipeline(聚合管道)
MongoDB的聚合框架基于数据处理管道的概念。文档进入一个多级管道,将文档转换为聚合结果。比如文档的投影,过滤,排序,分组,等等。此外,管道阶段还可以使用操作符来执行任务,例如计算平均值或连接字符串等等。
下图为一个简单的聚合例子(此图来自mongodb的官网)
如上图所示:先使用 $match 构建筛选出 status 等于A 的数据,然后使用 $group 构建分组数据,以 cust_id 进行分组,使用 $sum 进行分组的求和操作。
聚合管道的限制
1、文档大小限制
聚合的返回单个文档不可超过16M,但是聚合的过程中单个文档可以超过16M.
2、内存的限制
聚合阶段默认情况下可以使用100M的内存,超过则报错。如果想处理需要超过100M内存的数据,则需要将 allowDiskUse 设置成 true,让其可以写入临时文件。但是在 $graphLookup 阶段,内存还是限制到100M以内,即使设置了 allowDiskUse=true, 在此管道阶段会失效,但是如果以其他的管道阶段还是会生效的。当allowDiskUser=false,内存超出发生异常。
聚合管道阶段
| $match | 用于过滤数据,用于聚合阶段的输入 |
| $order | 用指定的键,对文档进行排序 |
| $limit | 用于限制多少个文档作为输入 |
| $skip | 跳过多少个文档 |
| $project | 投影字段,可以理解为查询多少个字段,类似为 select a,b,c 中的 a,b,c |
| $group | 进行分组操作,其中_id字段用于指定需要分组的字段。 |
| $count | 返回这个聚合管道阶段的文档的数量 |
更多管道阶段,请点击 这里。
聚合管道操作,请点击 这里
基本语法
db.collection.aggregate( [ { <stage> }, ... ] )
准备数据
db.persons.insertMany([
{userId : '001',age : 24,salary : 5000,dept : '部门一'},
{userId : '002',age : 25,salary : 7000,dept : '部门二'},
{userId : '003',age : 23,salary : 8000,dept : '部门一'},
{userId : '004',age : 26,salary : 1000,dept : '部门三'},
{userId : '005',age : 27,salary : 2000,dept : '部门二'},
{userId : '006',age : 22,salary : 7000,dept : '部门一'},
{userId : '007',age : 25,salary : 6000,dept : '部门三'},
{userId : '008',age : 26,salary : 4000,dept : '部门三'},
{userId : '009',age : 28,salary : 9000,dept : '部门二'}
])
1、使用 $project 投影出需要的字段
* 排除 _id 字段
* 返回 age字段
* 产生一个新字段 newAge,它的值为原age字段的值 加 1
db.persons.aggregate([
{$project : {_id : 0,age : 1,newAge : {$add : ['$age',1]}}}
])
2、使用 $match 进行数据的过滤
和普通的查询条件是一样的。
db.persons.aggregate([
{$match : {age : {$gt : 22}} }
])
3、使用 $sort 进行排序
db.persons.aggregate([
{$match : {age : {$gt : 22}} },
{$sort : {age : 1}}
])
4、使用 $limit 和 $skip 进行限制数据和过滤数据
db.persons.aggregate([
{$match : {age : {$gt : 22}} },
{$sort : {age : -1}},
{$limit : 6},
{$skip : 3}
])
5、使用 $group 进行分组操作
db.persons.aggregate([
{$group : {_id : "$dept",count : {$sum : 1}}}
]);
有了以上的简单知识,我们完成一个简单的练习。
需求: 获取6个年龄大于22周岁的用户,其中如果薪水如果小于1000,直接将薪水上调到4000,前面一步做好后,需要排出年龄最大的一个,求出每个部门,相同年龄的员工的平均薪水,并得到薪水最高的三个人。
思路:1、投影出年龄(age),部分(dept),薪水(salary)字段
2、查出年龄大于22周岁的员工
3、以年龄倒叙进行排序
4、限制返回7条数据,并跳过一条数据
5、以部门年龄进行分组,并求出平均分
6、以上一步的平均分在进行倒叙排序
7、然后再返回3条数据
代码如下
db.persons.aggregate([
{ $project : {age : 1,dept : 1,oldSalary : "$salary",salary : {
$switch : {
branches : [
{ case : { $lte : ["$salary",1000] }, then : {$sum : ["$salary",4000]}}
],
default : '$salary'
}
}} },
{ $match : {age : {$gt : 22}} },
{ $sort : {age : -1}},
{ $limit : 7},
{ $skip : 1 },
{ $group : { _id : {dept : "$dept",age : "$age"},pers : {$sum : 1} , deptAvgSalary : { $avg : "$salary"} } },
{ $sort : {deptAvgSalary : -1}},
{ $limit : 3}
]);
运行效果
mongodb的聚合操作的更多相关文章
- Yii2的mongodb的聚合操作
最近项目使用到mongodb的聚合操作,但是yii文档中对这方面资料较少,记录下 $where['created_time'] = ['$gt' => "$start_date_str ...
- MongoDB的聚合操作以及与Python的交互
上一篇主要介绍了MongoDB的基本操作,包括创建.插入.保存.更新和查询等,链接为MongoDB基本操作. 在本文中主要介绍MongoDB的聚合以及与Python的交互. MongoDB聚合 什么是 ...
- MongoDB入门---聚合操作&管道操作符&索引的使用
经过前段时间的学习呢,我们对MongoDB有了一个大概的了解,接下来就要开始使用稍稍深入一点的东西了,首先呢,就是MongoDB中的聚合函数,跟mysql中的count等函数差不多.话不多说哈,我们先 ...
- mongodb aggregate 聚合 操作(扁平化flatten)
mongodb自带的函数非常多,最近用mongo做持久化数据库,遇到一个需求:子文档是个数组,把数组里的各个字段扁平化合到根文档中,查过资料后(主要是mongodb的文档和stackoverflow) ...
- mongodb高级聚合查询
在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysql复杂很多. 注:本文基于 mo ...
- mongodb高级聚合查询(转)
在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysql复杂很多. 注:本文基于 mo ...
- mongodb 高级聚合查询
mongodb高级聚合查询 在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysq ...
- MongoDB 聚合操作
在MongoDB中,有两种方式计算聚合:Pipeline 和 MapReduce.Pipeline查询速度快于MapReduce,但是MapReduce的强大之处在于能够在多台Server上并行执行复 ...
- MongoDB学习笔记——聚合操作之聚合管道(Aggregation Pipeline)
MongoDB聚合管道 使用聚合管道可以对集合中的文档进行变换和组合. 管道是由一个个功能节点组成的,这些节点用管道操作符来进行表示.聚合管道以一个集合中的所有文档作为开始,然后这些文档从一个操作节点 ...
随机推荐
- Mybatis-基本学习(下)
四,MAP的使用--超常用 思考:多表连接查询怎么做?---MAP的好处!---返回List
- 从输入 URL 到展现页面的全过程
总体分为以下几个过程 DNS解析 TCP连接 发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 连接结束 DNS解析 域名到ip地址转换 TCP连接 HTTP连接是基于TCP连接 ...
- Azure 实践(4)- CI/CD .netcore项目Docker构建及部署
上篇已介绍了.netcore项目构建的相关步骤,本篇继续完善 1.什么是CI/CD CI/CD 中的"CI"始终指持续集成,它属于开发人员的自动化流程.成功的 CI 意味着应用代码 ...
- 进程代数CSP基础知识总结(Communicating sequencing process)
进程代数(Process Algebra) Process Algebra 理论 提出者 理论名称 缩写 论文链接 简介 C. A. R. Hoare/Tony Hoare Communicating ...
- PHP的Mcrypt加密扩展知识了解
今天我们来学习的是 PHP 中的一个过时的扩展 Mcrypt .在 PHP7 之前,这个扩展是随 PHP 安装包一起内置发布的,但是现在新版本的 PHP 中已经没有了,需要使用这个扩展的话我们需要单独 ...
- PHP执行数据库定时备份 和手动还原
一 备份数据库 我的这个是在TP5上,其实不在TP5也可以 逻辑: 1 首先在自己电脑的cmd命令上测试备份数据库,成功才能往下进行所以得到 C:/luanxiede/mysql-5.7/bin/my ...
- Java基础系列(22)- For循环详解
For循环 虽然所有循环结构都可以用while和dowhile表示,但是Java提供了另外一种语句for循环,使一些循环结构变动更加简单 for循环语句是支持迭代的一种通用结构,是最有效.最灵活的循环 ...
- 一朵云、一张网、一体化 ——GRTN 打造最佳流媒体场景实践
阿里巴巴 GRTN 是面向流媒体云原生设计的,方便客户构建自己的流媒体云原生应用,让流媒体服务无处不在. 在近期召开的分布式云主题报告会上,阿里云资深技术专家卢日发表了题为<GRTN 打造阿里云 ...
- Jmeter线程组设置
添加线程组:右键测试计划->添加->Threads->线程组 左侧树形标签栏中,显示标签信息. 选中线程组,右侧内容栏中显示线程组的相关信息. 名称:可以给线程组设置一个个性化的命名 ...
- 微信小程序 创建自己的第一个小程序
* 成为微信公众平台的开发者 注册 https://mp.weixin.qq.com * 登录 https://open.weixin.qq.com/ * 开发者工具下载 https://develo ...