聚合框架的基本思路是:采用多个构件来创建一个管道,用于对一连串的文档进行处理。这些构件包括:筛选(filtering)、投影(projecting)、分组(grouping)、排序(sorting)、限制(limiting)和跳过(skipping)。
使用聚合框架的方式 db.集合.aggregate(构件1,构件2…)
注意:由于聚合的结果要返回到客户端,因此聚合结果必须限制在16M以内,这是MongoDB支持的最大响应消息的大小
示例
找出考80分以上的课程门数最多的3个学生
是用聚合框架来完成功能的步骤
- 找到所有考了80分以上的学生,不区分课程 {"$match":{"score":{$gte:80}}}
- 将每个学生的名字投影出来 {"$project":{"studentId":1}}
- 对学生的名字排序,某个学生的名字出现一次,就给他加1 {"$group":{"_id":"$studentId","count":{"$sum":1}}}
- 对结果集按照count进行降序排列 {"$sort":{"count":-1}}
- 返回前面的3条数据 {"$limit":3}
执行语句
db.scores.aggregate({"$match":{"score":{$gt:80}}},{"$project":{"studentId":1,"course":1}},{"$group":{"_id":"$studentId","count":{$sum:1}}},{$sort:{"count":-1}},{$limit:3});
$project
用来从文档中提取字段,可以指定包含和排除字段,也可以重命名字段。
管道操作符$project的数学表达式
$add : [expr1[,expr2,…exprn]]
$subtract:[expr1,expr2]
$multiply:[expr1[,expr2,…exprn]]
$divice:[expr1,expr2]
$mod:[expr1,expr2]
比如给成绩集体加20分,如下
db.scores.aggregate({"$project":{"score":{$add:["$score",20]}}});
$group
用来将文档依据特定字段的不同值进行分组。选定了分组字段过后,就可以把这些字段传递给$group函数的“_id”字段了
db.scores.aggregate({“$group”:{“_id”:“$studentId”}}); 或者是 db.scores.aggregate({"$group":{"_id":{"sid":"$studentId","score":"$score"}}});
$group支持的操作符
$sum:value :对于每个文档,将value与计算结果相加
$avg:value :返回每个分组的平均值
$max:expr :返回分组内的最大值
$min:expr :返回分组内的最小值
db.scores.aggregate({"$group":{"_id":"$studentId","avg":{"$avg":"$score"},"sum":{"$sum":"$score"},"max":{"$max":"$score"}}});
$first:expr :返回分组的第一个值,忽略其他的值,一般只有排序后,明确知道数据顺
序的时候,这个操作才有意义
$last:expr :与上面一个相反,返回分组的最后一个值
$addToSet:expr :如果当前数组中不包含expr,那就将它加入到数组中
$push:expr:把expr加入到数组中
拆分命令:$unwind
用来把数组中的每个值拆分成为单独的文档。
db.user.aggregate({"$unwind":"$house"});