聚合框架
使用聚合框架可以对集合中的文档进行变换和组合。可以用多个构件创建一个管道(pipeline,类似一个流),用于对一连串的文档进行处理。这些构件包括:
筛选(filtering)
投射(projecting)
分组(grouping)
排序(sorting)
限制(limiting)
跳过(skipping)
聚合的结果必须要限制在16M之内(MongoDB支持的最大的响应大小)。
要将每个操作传给aggreagte()函数。
db.集合.aggregate(构件1,构件2…)
//有一个保存着杂志文章的集合,找出发表文章最多的那个作者
db.articles.aggregate({
$project:{
"author":1}},${
$group:{
"_id":"$author","count":{
"$sum":1}}},{
$sort:{
"count":-1}},{
$limit:5})
每个操作符都会接受一连串的文档,对这些文档做一些操作,最后将转换后的文档作为结果传递给下一个操作符(最后一个操作符是将结果返回给客户端)
不同的管道操作符可以按任意组合任意顺序一起使用,而且可以被重复多次使用。
管道操作符
1、$match
$match用于对文档进行筛选,可以使用所有常规的查询操作符 。
//查询性别为男的用户
{
$match:{
"sex":"男"}}
//查询工资为10000以上的员工
{
$match:{
"saler":{
$gt:10000}}}
应该尽可能将“$match”放在管道的前面:
- 一是可以快速将不需要的文档过滤掉,减少管道的工作量
- 二是在投射和分组之前执行“$match”,查询可以使用索引
2、$project
使用”$project”可以从文档中提取字段(只返回想要的字段),可以重命名字段.
1、从文档中选择想要的字段,可以指定包含或不包含一个字段
//指定只返回author字段(默认都包含“_id”字段,必须显式声明"_id":0,才不包含"_id"字段)
db.articles.aggregate({$project:{
"author":1}})
2、将字段重命名
//将每个用户文档的"_id"再返回结果中重命名为"userId"
db.users.aggregate({
$project:{
"userId":"$_id","_id":0}})
{ "userId" : ObjectId("5b3c7f2020306147a4f53537") }
//必须明确指定将"_id"排除,否则会出现下面这种结果
{ "_id":ObjectId("5b3c7f2020306147a4f53537"), "userId" : ObjectId("5b3c7f2020306147a4f53537") }
//”$fieldname“语法是为了在聚合框架中引用fieldname字段的值,例如 ”$age“会被替换为"age"字段的内容,上面的"$_id"会被替换为进入管道的问个文档的"_id"字段的值
在字段进行重命名时,MongoDB不会记录字段的历史名称,即在”id”字段上有索引,重命名成”userId”后,在之后的操作中不能使用“_id”的索引。所以尽量在修改字段名称前使用索引。
3、$group
group可以将文档根据特定字段的不同值进行分组,将分组的字段传递给”group”函数的”_id”字段
//按课程分组
{$group:{
"_id":"course"}}
//按成绩分组
{$group:{
"_id":"grade"}}
$group可以使用的操作符:
1: sum:value:对于每个文档,将value与计算结果相