聚合 aggregate
- 聚合(aggregate)主要用于计算数据,类似sql中的sum()、avg()
- 语法
db.集合名称.aggregate([{管道:{表达式}}])
管道
- 管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的输入
ps ajx | grep mongo
- 在mongodb中,管道具有同样的作用,文档处理完毕后,通过管道进行下一次处理
- 常用管道
- $group:将集合中的文档分组,可用于统计结果
- $match:过滤数据,只输出符合条件的文档
- $project:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
- $sort:将输入文档排序后输出
- $limit:限制聚合管道返回的文档数
- $skip:跳过指定数量的文档,并返回余下的文档
- $unwind:将数组类型的字段进行拆分
表达式
- 处理输入文档并输出
- 语法
表达式:‘$列名‘
- 常用表达式
- $sum:计算总和,$sum:1同count表示计数
- $avg:计算平均值
- $min:获取最小值
- $max:获取最大值
- $push:在结果文档中插入值到一个数组中
- $first:根据资源文档的排序获取第一个文档数据
$last:根据资源文档的排序获取最后一个文档数据
$group
- 将集合中的文档分组,可用于统计结果
- _id表示分组的依据,使用某个字段的格式为‘$字段‘
- 例1:统计男生、女生的总人数
8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY> db.stu.aggregate([{$group:{_id:‘$gender‘,count:{$sum:1}}}]) 8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY> db.stu.find() { "_id" : ObjectId("5ef1d0b85192e418c6c6e198"), "name" : "zmd", "age" : 22, "gender" : true } { "_id" : ObjectId("5ef1d0df5192e418c6c6e199"), "name" : "tdq", "age" : 28, "gender" : true } { "_id" : ObjectId("5ef1d0f25192e418c6c6e19a"), "name" : "yanmeihua", "age" : 28, "gender" : false } { "_id" : ObjectId("5ef1d10b5192e418c6c6e19b"), "name" : "qjj", "age" : 20, "gender" : false } 8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY> db.stu.aggregate([{$group:{_id:‘$gender‘,count:{$sum:1}}}]) { "_id" : false, "count" : 2 } { "_id" : true, "count" : 2 } 8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY>
Group by null
- 将集合中所有文档分为一组
- 例2:求学生总人数、平均年龄
8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY> db.stu.aggregate([{$group:{_id:null,count:{$sum:1},avgAge:{$avg:‘$age‘}}}]) { "_id" : null, "count" : 4, "avgAge" : 24.5 }
透视数据
- 例3:统计学生性别及学生姓名
8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY> db.stu.aggregate([{$group:{_id:‘$gender‘,name:{$push:‘$name‘}}}]) { "_id" : false, "name" : [ "yanmeihua", "qjj" ] } { "_id" : true, "name" : [ "zmd", "tdq" ] } 8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY>
- 使用$$ROOT可以将文档内容加入到结果集的数组中,代码如下
8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY> db.stu.aggregate([{$group:{_id:‘$gender‘,name:{$push:‘$$ROOT‘}}}]).pretty() { "_id" : false, "name" : [ { "_id" : ObjectId("5ef1d0f25192e418c6c6e19a"), "name" : "yanmeihua", "age" : 28, "gender" : false }, { "_id" : ObjectId("5ef1d10b5192e418c6c6e19b"), "name" : "qjj", "age" : 20, "gender" : false } ] } { "_id" : true, "name" : [ { "_id" : ObjectId("5ef1d0b85192e418c6c6e198"), "name" : "zmd", "age" : 22, "gender" : true }, { "_id" : ObjectId("5ef1d0df5192e418c6c6e199"), "name" : "tdq", "age" : 28, "gender" : true } ] } 8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY>
$match
- 用于过滤数据,只输出符合条件的文档
使用MongoDB的标准查询操作
例1:查询年龄大于20的学生
8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY> db.stu.find() { "_id" : ObjectId("5ef1d0b85192e418c6c6e198"), "name" : "zmd", "age" : 22, "gender" : true } { "_id" : ObjectId("5ef1d0df5192e418c6c6e199"), "name" : "tdq", "age" : 28, "gender" : true } { "_id" : ObjectId("5ef1d0f25192e418c6c6e19a"), "name" : "yanmeihua", "age" : 28, "gender" : false } { "_id" : ObjectId("5ef1d10b5192e418c6c6e19b"), "name" : "qjj", "age" : 20, "gender" : false } 8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY> db.stu.aggregate([{$match:{age:{$gt:20}}}]) { "_id" : ObjectId("5ef1d0b85192e418c6c6e198"), "name" : "zmd", "age" : 22, "gender" : true } { "_id" : ObjectId("5ef1d0df5192e418c6c6e199"), "name" : "tdq", "age" : 28, "gender" : true } { "_id" : ObjectId("5ef1d0f25192e418c6c6e19a"), "name" : "yanmeihua", "age" : 28, "gender" : false } 8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY>
- 例2:查询年龄大于20的男生、女生人数
8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY> db.stu.aggregate([{$match:{age:{$gt:20}}},{$group:{_id:"$gender",counter:{$sum:1}}}]) { "_id" : false, "counter" : 1 } { "_id" : true, "counter" : 2 } 8e08b0f0-7db1-49aa-8274-05c3bca10e67:PRIMARY>