1、介绍
MongoDB中聚合主要用于处理数据,例如统计平均值、求和等,并返回计算后的数据。
MongoDB中聚合的方法使用aggregate()。
//基本语法:
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
集合数据如下(后期操作均在Students集合的基础上进行操作):
2、常用管道操作符
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
3、常用表达式操作符
4、$group
g r o u p 是 一 个 管 道 操 作 符 , 获 得 的 结 果 可 以 接 着 输 出 到 下 一 个 管 道 , 内 部 的 group是一个管道操作符,获得的结果可以接着输出到下一个管道,内部的 group是一个管道操作符,获得的结果可以接着输出到下一个管道,内部的sum是一个表达式操作符。
从下例中可看出:
这里的_id字段表示你要基于哪个字段来进行分组(即制定字段值相同的为一组),这里的
a
g
e
就
表
示
要
基
于
a
g
e
字
段
来
进
行
分
组
。
下
面
的
n
u
m
字
段
的
值
age就表示要基于age字段来进行分组。 下面的num字段的值
age就表示要基于age字段来进行分组。下面的num字段的值sum: 1表示的是获取满足age字段相同的这一组的数量乘以后面给定的值(本例为1,那么就是同组的数量)。 也就是分组后每个age值的数量。
//将document分组,用作统计结果
db.Students.aggregate([ // aggregate方法接收的是一个数组
{
$group: {
_id: '$age',
num: {$sum: 1}
}
}
])
下例中可看出,age相同的document被分为了一组,而且使用$push表达式,将我们指定的document的name字段的值也放到了一个数组中作为问哦们在MongoDB语句中指定的stuName的值。
db.Students.aggregate([
{
$group: {
_id: '$age',
stuName: {$push: '$name'}
}
}
])
5、$match
//这样就拿到了所有age>15的document,因为$match是一个管道操作符,$match得出来的结果可以给下一个管道使用,所以可以通过再接个管道来进行其他的操作。
db.Students.aggregate([
{
$match: {
age: {$gt: 15}
}
}
])
输出结果为:
//在$match的基础上,在接一个$group来进行分组,显示筛选出来的所有age>15的文档个数。
db.Students.aggregate([
{
$match: {
age: {$gt: 15}
}
},
{
//在$match的结果基础上再进行分组。
$group:{
_id:'$age',//_id: null表示全选
num:{$sum:1}
}
}
])
输出结果为:
6、$project
修改输入文档的结构(例如重命名,增加、删除字段,创建结算结果等)
$project和直接使用find()的写法一样。
//db.Students.find({},{'_id': 0})
db.Students.aggregate([
{
$project: {
_id: 0, //不显示_id字段
}
}
])
输出结果:
现在可以把通道搭配起来,拿到数据:age>15 的document的name字段。
db.Students.aggregate([
{
//删选age>15的document
$match: {
age: {$gt: 15}
}
},
{
//不显示_id字段,显示name字段
$project: {
_id: 0, //不显示_id字段
name:1
}
},
{
//对以上操作的结果进行分组
$group:{
_id:null,
stuName:{$push:'$name'}
}
}
])
输出结果为:
7、$sort
$sort和我们find()中排序的写法也是一样的。
将集合中的所有数据按照age降序排列
db.Students.aggregate([
{
$sort:{
age:-1
}
}
])
8、$limit $skip
与limit()和skip()方法写法一样。
注意:先写skip,再写limit
//从第0个开始,跳过2个document取2个
db.Students.aggregate([
{$skip: 2},
{$limit:2}
])
9、$unwind
$unwind管道可以document中的数组类型的字段进行拆分,每条包含数组中的一个值。
db.Students.aggregate([
{
//先筛选出'张三'的数据
$match:
{
name:'张三'
}
},
{
//对'张三'的爱好进行拆分
$unwind:'$hobbies'
}
])
输出结果:
已将’张三‘的hobbies进行了拆分,每条数据包含一个爱好。