mongoDB聚合操作
mongoDB聚合常用的管道有
- $match: 过滤管道过滤数据,只输出符合条件的文档
- $group: 将集合中的文档分组,可用于统计结果
- $project 映射管道,映射输出
- $sort: 排序管道,将输入文档排序后输出
- $limit: 限制管道,限制聚合管道返回的文档书
- $skip: 跳过管道,跳过指定数量的文档,并返回余下的文档
1.准备一组数据
db.data.insertMany([{name:"Tom", city:"cityA",type:"aaa",num:609,age:18}, {name : "allen", city :"cityC", type: "bbb", num : 549,age:20}, {name :"jerry", city :"cityA", type :"bbb", num : 593,age:22}, {name :"frank", city : "cityB", type:"aaa", num : 657,age:21}, {name :"jack", city : "cityC", type:"aaa", num : 620,age:18}, {name :"alice", city : "cityB", type:"ccc", num : 584,age:20}, {name :"marry", city:"cityA", type:"bbb", num : 599,age:22} ])
db.data.find()
2.$group 分组管道
2.1 统计单组
对city分组,并求每组num的平均值。
db.data.aggregate({$group:{_id:'$city',avg_num:{$avg:'$num'}}})
2.2 统计多组
db.data.aggregate({$group:{_id:'$city',avg_num:{$avg:'$num'},avg_age:{$avg:'$age'}}})
3.$match 过滤管道
可以将其作用结果传给后一个管道。
对city不是"cityC"的city分组(过滤掉“”cityC"),并求每组num的平均值。
db.data.aggregate({$match:{city:{$ne:"cityC"}}},{$group:{_id:'$city',avg_num:{$avg:'$num'}}})
对age≥20的city分组(过滤掉“”cityC"),并求每组num的平均值。
db.data.aggregate({$match:{age:{$gte:20}}},{$group:{_id:'$city',avg_num:{$avg:'$num'}}})
其中,
_id是分组的依据
avg_num是新定义的字段名
$avg 是求值方法的表达式,这里是求平均值的表达式
‘$city’ 指定的分组依据
‘$num’ 指定的要求值的字段
拓展 统计数据个数
如果要统计每组数据的个数,则可以使用 $sum 实现。
$sum的功能是求某字段的和,用$sum计数时,如统计每个city的人数,可以写成:
db.data.aggregate({$group:{_id:'$city',count:{$sum:1}}})
即对字段,常数1进行计数。如果写为{$sum:2},则计数结果为4,4,6。
4.$project 映射管道
db.data.aggregate({$group:{_id:'$city',avg_num:{$avg:'$num'},avg_age:{$avg:'$age'}}},{$project:{avg_num:1}})
如图,结果不再显示avg_age,只显示了_id和avg_num。
5.$sort $skip $limit
按年龄降序排列,跳过第一条,取前三条数据
db.data.aggregate({$sort:{age:-1}},{$skip:1},{$limit:3})
按年龄降序排列,取前三条数据,跳过第一条,
db.data.aggregate({$sort:{age:-1}},{$limit:3},{$skip:1})
取前三个数据,跳过第一个,再降序排列
db.data.aggregate({$limit:3},{$skip:1},{$sort:{age:-1}})
管道的写法不用考虑优先级的问题,从左到右依次执行。
6.常用表达式补充
$sum: 计算总和, $sum:1 表示以⼀倍计数
$avg: 计算平均值
$min: 获取最⼩值
$max: 获取最⼤值
$push: 在结果⽂档中插⼊值到⼀个数组中
$first: 根据资源⽂档的排序获取第⼀个⽂档数据
$last: 根据资源⽂档的排序获取最后⼀个⽂档数据
版权声明:除特别声明外,本站所有文章皆是本站原创,转载请以超链接形式注明出处!