1 聚合是什么
聚合管道是指每个文档通过一个由多个阶段组成的管道,前面管道的结果作为后面管道的输入,可以对每个阶段管道进行分组、过滤等功能,然后经过一系列处理,输出相应结果。
2 mongodb常用管道和表达式
2.1 常用管道命令
$group
:将集合中的文档分组,可用于统计结果(分组管道)
$match
:过滤数据,只输出符合条件的文档(过滤管道)
$project
:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
$sort
:将输入文档排序后输出
$limit
:限制聚合管道返回的文档数
$skip
:跳过指定数量的文档,并返回余下文档
2.2 常用表达式
表达式:处理输入文档并输出 语法:表达式:‘$列名’
$sum
:计算总和
$avg
:计算平均值
$min
:获取最小值
$max
:获取最大值
$push
:在结果文档中插入值到一个数组
3 管道命令之$group
将集合中的文档分组,可用于统计结果
3.1 按照某个字段进行分组
用gender的值对集合进行分组,返回键"_id":
db.__.aggregate({$group:{_id:"$gender"}})
(_id、counter 出现在结果中)
counter计数器,sum:1 规定每次累加1
db.__.aggregate({$group:{_id:"$gender",counter:{$sum:1}}})
"$age"取年龄,sum加总和
db.__.aggregate({$group:{_id:"$gender"},counter:{$sum:1},sum_age:{$sum:"$age"}})
“$age” 取年龄,avg计算平均值
db.__.aggregate({$group:{_id:"$gender"},counter:{$sum:1},sum_age:{$sum:"$age"},avg_age:{$avg:"$age"}}})
push:把每一条数据name放到name_list中去(name_list出现在结果中)
db.__.aggregate({$group:{_id:"$gender"},counter:{$sum:1},sum_age:{$sum:"$age"},avg_age:{$avg:"$age"},name_list:{$push:"$name"}}})
3.2 group by null
不分组做统计:
db.__.aggregate({$group:{_id:null,counter:{$sum:1}}})
3.3 数据透视
db.__.aggregate({$group:{_id:null,name_list:{$push:"$name"}})
4 管道命令之$match
过滤数据,只输出符合条件的文档
过滤显示集合中age=18的数据
db.__.aggregate({$match:{age:18}}})
过滤显示集合中name中有’黄‘的数据
db.__.aggregate({$match:{name:/黄/}}})
先match再group
db.__.aggregate({$match:{age:18},{$group:{_id:"$gender"},name:{$push:"$name"}}})
5 管道命令之$project
修改输入文档的结构,如重命名、增加、删除字段、创建计算结果(投影)
$project:{name:1}:显示name
db.__.aggregate({$match:{age:18},{$group:{_id:"$gender"},name:{$push:"$name"},avg_age:{$avg:"$age"}}},{$project:{name:1}})
6 管道命令之$sort
将输入文档排序后输出
1升序;-1降序
db.__.aggregate({$sort:{age:1},{gender:-1}})
7 管道命令之$limit
限制聚合管道返回的文档数
db.__.aggregate({$limit:1})
8 管道命令之$skip
跳过指定数量的文档,并返回余下文档
db.__.aggregate({$skip:1})
先limit再skip
db.__.aggregate({$limit:2},{$skip:1}})
先skip再limit
db.__.aggregate({$skip:1},{$limit:2}})
先limit再skip和先skip再limit结果不一样!
9 拆分管道$unwind
按size值进行拆分
db.__.aggregate({$unwind:"$size"})
size为空的也显示
db.__.aggregate({$unwind:{path:"$size",preserveNullAndEmptyArrays:true}})