MongoDB 聚合
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
aggregate() 方法
MongoDB中聚合的方法使用aggregate()。类似sql语句中的 count(*)。
aggregate() 返回的结果还是一个文档{},表达式里必须包含_id属性,否则会报错。
_id表示分组的依据,使用某个字段的格式为'$字段'。
语法
aggregate() 方法的基本语法格式如下所示:
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
管道
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
聚合框架中常用的管道操作符
- $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
- $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
- $limit:用来限制MongoDB聚合管道返回的文档数。
- $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
- $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
- $group:将集合中的文档分组,可用于统计结果。
- $sort:将输入文档排序后输出。
- $geoNear:输出接近某一地理位置的有序文档。
列操作表达式
处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
语法
- 表达式 : '$列名'
常用表达式
- $sum:计算总和,$sum:1同count表示计数。
- $avg:计算平均值。
- $min:获取最小值。
- $max:获取最大值。
- $push:在结果文档中插入值到一个数组中。
- $first:根据资源文档的排序获取第一个文档数据。
- $last:根据资源文档的排序获取最后一个文档数据。
聚合操作实例
创建集合
首先,在数据库中创建如下集合:
db.c1.insertMany([
{name:"tom", age:18, gender:"男"},
{name:"lin", age:18, gender:"男"},
{name:"jenney", age:16, gender:"女"},
{name:"klay", age:20, gender:"男"}
])
注意,age 属性对应内容是数字 18 而不是字符串"18",否则后续无法做数值处理。
查看集合所有文档:
db.c1.find()
$group操作
分别通过 name, age, gender 属性将文档分组统计个数
db.c1.aggregate([{$group : {_id : "$name", num_tutorial : {$sum : 1}}}])
db.c1.aggregate([{$group : {_id : "$age", num_tutorial : {$sum : 1}}}])
db.c1.aggregate([{$group : {_id : "$gender", num_tutorial : {$sum : 1}}}])
_id 如果乱写相当于写null,全部计数
db.c1.aggregate([{$group : {_id : "$lol", num_tutorial : {$sum : 1}}}])
db.c1.aggregate([{$group : {_id : null, num_tutorial : {$sum : 1}}}])
$match操作
找出“age大于17,小于等于20”的文档
db.c1.aggregate( [
{ $match : { age : { $gt : 17, $lte : 20 } } }
]);
管道组合操作
“age大于17,小于等于20”的文档个数
db.c1.aggregate( [
{ $match : { age : { $gt : 17, $lte : 20 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
]);
将“age大于10,小于等于20”的文档按性别统计
db.c1.aggregate( [
{ $match : { age : { $gt : 10, $lte : 20 } } },
{ $group: { _id: "$gender", count: { $sum: 1 } } }
]);