mongodb聚合(aggregate)

PS:关于mongodb增删改查以及高级查询博文可以参考 mongodb增删改查 在mongodb中,通过聚合,当数据由一个管道处理完毕之后,会将这些处理完的数据交给下一个管道进行再次处理,最终得到我们需要的数据,输出相应的结果。

db.集合名称.aggregate({管道命令:{表达式}})

 1. 常用的管道命令
 	$group:将集合中的数据进行分组,可用于统计结果,_id表示分组的依据
 		例如:统计男生、女生的各多少人
 		db.student.aggregate(
			{$group:
				{
					_id : "$gender",
					counter : {$sum : 1}
				}
			}
		)	
		结果:{ "_id" : "woman", "counter" : 2 }
			 { "_id" : "man", "counter" : 2 }
		
		若分组依据为null,即
		db.student.aggregate(
			{$group:
				{
					_id : null,
					counter : {$sum : 1}
				}
			}
		)	
		结果:{ "_id" : null, "counter" : 4 }
		结果也变为,获取全部学生人数,不区分男生女生



 	$match:过滤数据,只输出符合条件的数据,然后交给下一个管道进行处理
 		例如:统计所有年龄大于16岁的学生,男生、女生各多少人
 		db.student.aggregate(
 			{$match:
 			 	{age: {$gt : 16}}
 			},
			{$group:
				{
					_id : "$gender",
					counter : {$sum : 1}
				}
			}
		)	
		结果:{ "_id" : "woman", "counter" : 1 }
		     { "_id" : "man", "counter" : 1 }

 		
 		
 	$project:修改输入数据的结构,如重命名,增加,删除字段,创建计算结果
		关于查询条件采用标准查询条件即可,详细可看之前我写的mongodb增删改查博文,拉到底部
		高级查询
		
 		例如:统计男生、女生各多少人,不显示_id, 统计人数重命名为count
 		db.student.aggregate(
			{$group:
				{
					_id : "$gender",
					counter : {$sum : 1}
				}
			},
			{$project:
				{_id : 0, count: "$counter"}
			}
		)	
		结果:{ "count" : 2 }
				   { "count" : 2 }



    $sort:将输入数据排序后输出
    	例如:查询班级男生,并且按年龄、姓名降序排序
    	db.student.aggregate(
		    {
		        $match: 
		        {
		            gender : "man"
		        }
		    },
		    {
		        $sort: 
		        {
		            age : - 1,
		            name : -1
		        }
		    },
		    {
		        $project: 
		        {
		            _id : 0
		        }
		    }
		)
		结果:{ "name" : 1, "gender" : "man", "age" : 20 }
			 { "name" : 5, "gender" : "man", "age" : 15 }  # 注意看name5,name3
			 { "name" : 3, "gender" : "man", "age" : 15 }



    $limit:限制聚合管道返回的数据数
    	例如:查询班级一条男生数据
    	db.student.aggregate(
		    {
		        $match: 
		        {
		            gender: "man"
		        }
		    },
		    {
		        $limit: 1
		    }
		)
    	结果:{ "_id" : ObjectId("5d19cdf24d59000088001146"), "name" : 1, "gender" : "man", "age" : 20 }



 	$skip:跳过指定数量的数据,并返回剩下的数据
 		例如:查询班级第一条以后的所有男生数据(即跳过第一条)
		db.student.aggregate(
		    {
		        $match: 
		        {
		            gender: "man"
		        }
		    },
		    {
		        $skip: 1
		    }
		)
		结果:{ "_id" : ObjectId("5d19ce264d59000088001148"), "name" : 3, "gender" : "man", "age" : 15 }
			 { "_id" : ObjectId("5d19d6374d5900008800114a"), "name" : 5, "gender" : "man", "age" : 15 }
		
		例如:分页操作,查询班级所有男生信息,一页2条数据,查询第二页信息(即跳过第一页,也就是前两条数据),现在student集合所有男生数据[1, 3, 5, 6, 7] 按照分页规则,第二页信息应该为[5, 6]
		{"name" : 1, "gender" : "man", "age" : 20 }
		{"name" : 3, "gender" : "man", "age" : 15 }
		{"name" : 5, "gender" : "man", "age" : 15 }
		{"name" : 6, "gender" : "man", "age" : 19 }
		{"name" : 7, "gender" : "man", "age" : 20 }
		
		db.student.aggregate(
		    {
		        $match: 
		        {
		            gender: "man"
		        }
		    },
		    {
		        $skip: 2
		    },
		    {
		        $limit: 2
		    }
		)	
		结果:{ "_id" : ObjectId("5d19d6374d5900008800114a"), "name" : 5, "gender" : "man", "age" : 15 }
			 { "_id" : ObjectId("5d19d8274d5900008800114b"), "name" : 6, "gender" : "man", "age" : 19 }



 	$unwind:将数组类型的字段拆分成多条,每条包含数组中的一个值
 		例如:假设clases集合中存在一组数据:
 		{
		    "_id": ObjectId("5d19db184d5900008800114d"),
		    "name": "一班",
		    "student_names": [1, 3, 5, 6, 7]
		}
		
		db.clases.aggregate(
		    {
		        $unwind: "$student_names"
		    }
		)
		结果:{ "_id" : ObjectId("5d19db184d5900008800114d"), "name" : "一班", "student_names" : 1 }
			 { "_id" : ObjectId("5d19db184d5900008800114d"), "name" : "一班", "student_names" : 3 }
			 { "_id" : ObjectId("5d19db184d5900008800114d"), "name" : "一班", "student_names" : 5 }
			 { "_id" : ObjectId("5d19db184d5900008800114d"), "name" : "一班", "student_names" : 6 }
			 { "_id" : ObjectId("5d19db184d5900008800114d"), "name" : "一班", "student_names" : 7 }

 2. 常用表达式 
	$sum:计算总和,$sum:1表示以一计数
	$avg:计算平均值
	$min:获取最小值
	$max:获取最大值
	$push:在数据中插入值到一个数组中
	$first:获取查询的第一个数据
	$last:获取查询的最后一个数据