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聚合管道 使用聚合管道可以对集合中的文档进行变换和组合. 管道是由一个个功能节点组成的,这些节点用管道操作符来进行表示.聚合管道以一个集合中的所有文档作为开始,然后这些文档从一个操作节点 ...
随机推荐
- MySQL数据库初体验
一.数据库的基本概念1.数据(Data) 描述事物的符号记录 包括数字,文字,图形,图像,声音,档案记录等 以"记录"形式按统一的格式进行存储 2.表 将不同的记录组织在一起 用来 ...
- utittest和pytest中mock的使用详细介绍
头号玩家 模拟世界 单元测试库介绍 mock Mock是Python中一个用于支持单元测试的库,它的主要功能是使用mock对象替代掉指定的Python对象,以达到模拟对象的行为. python3.3 ...
- [第三篇]——CentOS Docker 安装之Spring Cloud直播商城 b2b2c电子商务技术总结
CentOS Docker 安装 Docker 支持以下的 64 位 CentOS 版本: CentOS 7 CentOS 8 更高版本... 使用官方安装脚本自动安装 安装命令如下: curl -f ...
- linux关于profile 、bashrc 、.bash_profile、.bashrc的区别
linux关于profile .bashrc ..bash_profile..bashrc的区别 - /etc/profile /etc/bashrc ~/.bash_profile ~/.bashr ...
- xshell与小键盘问题
有些程序员的键盘是带有小数字键的,在使用xshell中文版时就可能出现一些小状况,本集就同大家分析一下使用数字键盘出现乱码的情况怎么办. 图1:使用数字小键盘出现乱码 问题描述: 在xshell上用v ...
- PHP中操作任意精度大小的GMP扩展学习
对于各类开发语言来说,整数都有一个最大的位数,如果超过位数就无法显示或者操作了.其实,这也是一种精度越界之后产生的精度丢失问题.在我们的 PHP 代码中,最大的整数非常大,我们可以通过 PHP_INT ...
- (一)es 概述与安装
一.基本概念介绍 1. es 核心术语 核心概念 ES -> 数据库 索引index -> 表 文档 document -> 行(记录) 字段 fields -> 列 早期版本 ...
- 写SQL的套路
定义问题 转化问题 如要解决的问题是:查出每门课程成绩都大于80分学生的姓名,可以转化为:只要学生最小分数的课程大于80分,就是所有课程成绩都大于80分. 查询同名同姓学生名单并统计同名人数--> ...
- 轻量级 Java 基础开发框架,Solon & Solon Cloud 1.5.40 发布
Solon 已有120个生态扩展插件,此次版本以细节打磨为主: 增加 mybatisplus-solon-plugin 插件 //至此,Solon 已完成国内外主流的5个ORM框架插件适配 插件 so ...
- 4-让线程睡眠的sleep方法
让线程睡眠的sleep方法 Thread类有一个静态的sleep方法,当一个执行中的线程调用了Thread的sleep方法,调用线程就会让出指定时间的执行权,也就是在这期间不参与CPU调度,但是该线程 ...