MongoDB学习笔记(三) 聚合

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: MongoDB学习笔记(三) 聚合

在数据库的实际应用中,我们常常需要使用聚合操作帮助我们处理数据,对数据进行统计和整理

这篇文章我们将会学习如何在MongoDB中使用聚合操作


1、聚合函数与聚合管道


使用聚合函数与聚合管道的基本语法格式如下:

db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)


常见的聚合函数如下:

聚合函数主要用于处理数据,例如求和、求平均值等,并返回最后的计算结果


操作符 描述
$sum 求和
$avg 求平均值
$min 求最小值
$max 求最大值
$first 获取第一个文档
$last 获取最后一个文档
$push 插入一个值到数组


常见的聚合管道如下:

聚合管道可以将上一个管道的处理结果传递给下一个管道继续处理


操作符 描述
$group 用于对文档进行分组
$project 用于修改文档结构,可以重命名、增加或删除字段
$match 过滤不符合条件的文档
$sort 对文档进行排序后输出
$limit 指定读取一定数量的记录数
$skip 指定跳过一定数量的记录数


好的,下面我们亲自来实验一下,首先准备好测试数据

> use university
> db.teacher.insert([
    {
        'tid': '19001',
      'name': 'Alice',
      'age': 32,
      'department': 'Computer',
      'salary': 10000
    },
    {
        'tid': '19002',
      'name': 'Bob',
      'age': 48,
      'department': 'Computer',
      'salary': 15000
    },
    {
        'tid': '19003',
      'name': 'Alice',
      'age': 42,
      'department': 'Software',
      'salary': 12000
    },
    {
        'tid': '19004',
        'name': 'Christy',
        'age': 38,
        'department': 'Software',
        'salary': 14000
    },
    {
        'tid': '19005',
        'name': 'Daniel',
        'age': 28,
        'department': 'Architecture',
        'salary': 8000
    }
])


统计所有教师的总工资

db.teacher.aggregate([
    {
        $group: {
            _id: null, // 不进行分组
            total_salary: { $sum: '$salary' } // 对 salary 字段的值进行累加
        }
    },
    {
        $project: {
            _id: 0, // 不输出 _id 字段
            total_salary: 1 // 输出 total_salary 字段
        }
    }
])
// 查询结果
// { "total_salary" : 59000 }


统计工资超过 10000 的教师的总人数

db.teacher.aggregate([
    {
        $match: {
            salary: { $gt: 10000 } // 返回 salary 字段的值大于 10000 的文档
        }
    },
    {
        $group: {
            _id: null, // 不进行分组
            total_teacher: { $sum: 1 } // 对数值 1 进行累加
        }
    },
    {
        $project: {
            _id: 0, // 不输出 _id 字段
            total_teacher: 1 // 输出 total_teacher 字段
        }
    }
])
// 查询结果
// { "total_teacher" : 3 }


统计每个学院教师的平均工资,并且按照平均工资从小到大的顺序输出

db.teacher.aggregate([
    {
        $group: {
            _id: '$department', // 以 department 字段的值进行分组
            avg_salary: { $avg: '$salary' } // 对 salary 字段的值求平均数
        }
    },
    {
        $project: {
            _id: 0, // 不输出 _id 字段
            dept_name: '$_id', // 增加 dept_name 字段,并将其值取为 _id 字段的值
            avg_salary: 1 // 输出 avg_salary 字段
        }
    },
    {
        $sort: {
            avg_salary: 1 // 按照 avg_salary 字段的值进行升序排列
        }
    }
])
// 查询结果
// { "avg_salary" : 8000, "dept_name" : "Architecture" }
// { "avg_salary" : 12500, "dept_name" : "Computer" }
// { "avg_salary" : 13000, "dept_name" : "Software" }


输出工资排名前三的教师的编号

db.teacher.aggregate([
    {
        $sort: {
            salary: -1 // 按照 salary 字段的值进行降序排列
        }
    },
    {
        $limit: 3 // 限制只能读取 3 条文档
    },
    {
        $project: {
            _id: 0, // 不输出 _id 字段
            tid: 1 // 输出 tid 字段
        }
    }
])
// 查询结果
// { "tid" : "19002" }
// { "tid" : "19004" }
// { "tid" : "19003" }


2、Map Reduce


除了聚合函数与聚合管道之外,MongoDB 中还存在另外一种更加灵活的聚合操作 —— Map Reduce

Map Reduce 是一种计算模型,它将大型工作分解(map)执行,再将结果合并(reduce)为最终结果


它的基本语法格式如下:

db.COLLECTION_NAME.aggregate(
    function() { emit(key, value) }, // map 函数,生成键值对序列,作为 reduce 函数的参数
    function(key, values) { return reduceFunction }, // reduce 函数,处理 values
    {
        query: <query>,   // 指定筛选条件,只有满足条件的文档才会调用 map 函数
        sort: <function>, // 在调用 map 函数前给文档排序
        limit: <number>,  // 限制发给 map 函数的文档数量
        finalize: <function>, // 在存入结果集合前修改数据
        out: <collection>,    // 指定结果存放的位置,若不指定则使用临时集合
    }
)


下面我们来举一个例子

统计每个学院年龄超过 30 的教师的平均工资超过 10000 的学院,但不输出关于工资的信息

db.teacher.mapReduce(
    // 2、执行 map 函数,map 函数的核心是调用 emit 函数,提供 reduce 函数的参数
    // emit 函数的第一个参数指定需要分组的字段,第二个参数指定需要进行统计的字段
    // 这里依据 department 字段的值分组,作为 key;组合 salary 字段的值成为数组,作为 values
    // 将每个分组得到的 (key, values) 作为 reduce 函数的参数传递过去
    function() { emit(this.department, this.salary) },
    // 3、执行 reduce 函数,reduce 函数的核心是将 (key, values) 变成 (key, value)
    // 该函数的参数 (key ,values) 从 map 函数而来,并返回一个处理后的值作为 value
    // value 与 key 组合成 (key, value) 再向后传递
    // 这里返回一个使用 avg 函数对 values 求得的平均值
    function(key, values) { return Array.avg(values) },
    {
        // 1、首先执行 query,筛选掉不符合条件的文档,然后将符合条件的文档发送到 map 函数
        query: { age: { $gt: 30 } },
        // 4、执行 finalize 函数,在将结果储存到 out 集合之前进行处理
        // 该函数的参数 (key, value) 从 reduce 函数而来,并返回一个处理后的值作为 value
        // 这里将平均工资信息隐藏,即将 value 字段的值设为 null
        finalize: function(key, value) {
            return null
        },
        // 5、将最终处理后的结果存到 total_teacher 集合
        out: 'total_teacher'
    }
)


可以看到输出如下

{
  "result" : "total_teacher", // 储存结果的集合名称
  "timeMillis" : 276, // 花费的时间,单位为毫秒
  "counts" : {
    "input" : 4, // 经过筛选后发送到 map 函数的文档个数
    "emit" : 4, // 在 map 函数中处理的文档个数
    "reduce" : 2, // 在 reduce 函数中处理的文档个数
    "output" : 2 // 结果集合的文档个数
  },
  "ok" : 1
}


然后查看结果

> show collections
// teacher
// total_teacher
> db.total_teacher.find()
// { "_id" : "Computer", "value" : null }
// { "_id" : "Software", "value" : null }


相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
25天前
|
SQL NoSQL Unix
MongoDB 聚合
10月更文挑战第17天
19 4
|
2月前
|
SQL NoSQL Unix
MongoDB聚合操作总结
这篇文章总结了MongoDB中聚合操作的作用、方法、常见聚合表达式以及聚合管道的概念和常用操作符,以及SQL与MongoDB聚合操作的对应关系。
41 2
MongoDB聚合操作总结
|
25天前
|
SQL NoSQL 数据处理
深入探索MongoDB的聚合操作
【10月更文挑战第13天】
11 0
|
2月前
|
NoSQL MongoDB 数据库
python3操作MongoDB的crud以及聚合案例,代码可直接运行(python经典编程案例)
这篇文章提供了使用Python操作MongoDB数据库进行CRUD(创建、读取、更新、删除)操作的详细代码示例,以及如何执行聚合查询的案例。
32 6
|
2月前
|
SQL NoSQL JavaScript
04 MongoDB各种查询操作 以及聚合操作总结
文章全面总结了MongoDB中的查询操作及聚合操作,包括基本查询、条件筛选、排序以及聚合管道的使用方法和实例。
75 0
|
3月前
|
持续交付 jenkins Devops
WPF与DevOps的完美邂逅:从Jenkins配置到自动化部署,全流程解析持续集成与持续交付的最佳实践
【8月更文挑战第31天】WPF与DevOps的结合开启了软件生命周期管理的新篇章。通过Jenkins等CI/CD工具,实现从代码提交到自动构建、测试及部署的全流程自动化。本文详细介绍了如何配置Jenkins来管理WPF项目的构建任务,确保每次代码提交都能触发自动化流程,提升开发效率和代码质量。这一方法不仅简化了开发流程,还加强了团队协作,是WPF开发者拥抱DevOps文化的理想指南。
82 1
|
3月前
|
NoSQL BI 数据处理
【超实用攻略】MongoDB 聚合框架:从入门到精通,带你解锁数据处理新姿势!
【8月更文挑战第24天】MongoDB是一款以其灵活性和高性能闻名的NoSQL数据库。其强大的聚合框架采用管道式处理,允许用户定义多个数据处理阶段如过滤、分组等。本文通过示例数据库`orders`和`products`,演示如何利用聚合框架计算各产品的总销售额。示例代码展示了使用`$lookup`连接两集合、`$unwind`打平数组及`$group`按产品ID分组并计算总销售额的过程。这突显了聚合框架处理复杂查询的强大能力,是进行数据分析和报表生成的理想选择。
50 3
|
3月前
|
存储 NoSQL JavaScript
MongoDB存储过程实战:聚合框架、脚本、最佳实践,一文全掌握!
【8月更文挑战第24天】MongoDB是一款备受欢迎的文档型NoSQL数据库,以灵活的数据模型和强大功能著称。尽管其存储过程支持不如传统关系型数据库,本文深入探讨了MongoDB在此方面的最佳实践。包括利用聚合框架处理复杂业务逻辑、封装业务逻辑提高复用性、运用JavaScript脚本实现类似存储过程的功能以及考虑集成其他工具提升数据处理能力。通过示例代码展示如何创建订单处理集合并定义验证规则,虽未直接实现存储过程,但有效地演示了如何借助JavaScript脚本处理业务逻辑,为开发者提供更多实用指导。
68 2
|
3月前
|
存储 NoSQL 数据处理
【MongoDB大神级操作】揭秘聚合框架,让你的数据处理能力瞬间飙升,秒变数据界的超级英雄!
【8月更文挑战第24天】MongoDB是一款备受欢迎的非关系型数据库,以其灵活的文档模型和出色的可扩展性著称。其聚合框架尤其亮眼,能高效地对数据库中的数据执行复杂的转换与聚合操作,无需将数据导出到应用端处理,极大提升了数据处理的效率与灵活性。例如,在一个大型电商数据库中,聚合框架能轻松分析出最热卖的商品或特定时段内某类别商品的销售总额。通过一系列管道操作,如$unwind、$group等,可以对数据进行逐步处理并得到最终结果,同时还支持过滤、排序、分页等多种操作,极大地丰富了数据处理的能力,成为进行数据分析、报表生成及复杂业务逻辑实现的强大工具。
73 2
|
3月前
|
持续交付 jenkins C#
“WPF与DevOps深度融合:从Jenkins配置到自动化部署全流程解析,助你实现持续集成与持续交付的无缝衔接”
【8月更文挑战第31天】本文详细介绍如何在Windows Presentation Foundation(WPF)项目中应用DevOps实践,实现自动化部署与持续集成。通过具体代码示例和步骤指导,介绍选择Jenkins作为CI/CD工具,结合Git进行源码管理,配置构建任务、触发器、环境、构建步骤、测试及部署等环节,显著提升开发效率和代码质量。
76 0