聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。
语法:db.集合名称.aggregate( {管道:{表达式}} )
8.2.1 常用管道命令
在mongodb中,文档处理完毕后,通过管道进行下一次处理 常用管道命令如下:
8.2.2 常用表达式
表达式:处理输入文档并输出 语法: 表达式:"$列名" 常用表达式:
8.3.1 按照某个字段进行分组
$group是所有聚合命令中用的最多的一个命令,用来将集合中的文档分组,可用于统计结果
使用实例如下:
db.stu.aggregate(
{$group:
_id:"$gender",
counter:{$sum:1}
}
)
注意点:
8.3.2 group by null
当我们需要统计整个文档的时候,$group的另一种用途就是把整个文档分为一组进行统计
使用实例如下:
db.stu.aggregate(
{$group:
{
_id:null,
counter:{$num:1}
}
}
)
注意点:
8.3.3 数据透视
正常情况下在统计的不同性别的数据的时候,需要知道所有的name,需要逐条观察,如果通过某种方式把所有的name放到一起,那么此时就可以理解为数据透视。
使用实例如下:
#1.统计不同性别的学生
db.stu.aggregate(
{$group:
{
_id:null,
name:{$push:"$name"}
}
}
)
#2.使用$$ROOT可以将整个文档放入数组中
db.stu.aggregate(
{$group:
{
_id:null,
name:{$push:"$$ROOT"}
}
}
)
m a t c h 用 于 进 行 数 据 的 过 滤 , 是 能 够 在 聚 合 操 作 中 使 用 的 命 令 , 和 f i n d 区 别 在 于 match用于进行数据的过滤,是能够在聚合操作中使用的命令,和find区别在于 match用于进行数据的过滤,是能够在聚合操作中使用的命令,和find区别在于match操纵可以把结果交给下一个管道处理,而find不行
使用实例如下:
#1.查询年龄大于20岁的学生
db.stu.aggregate(
{$match:{$age:{$gt:20}}}
)
#2.查询年龄大于20的男生和女生的人数
db.stu.aggregate(
{
$match:{$age:{$gt:20}}
{$group:{_id:"$gender"},counter:{$sum:1}}
}
)
$project用于修改文档的输入输出结构,列入重命名,增加,删除字段
使用实例如下:
#1.查询学生的年龄、姓名,仅输出年龄姓名
db.stu.aggregate(
{$project:{_id:0,name:1,age:1}}
)
#2.查询男生女生的人数,只输出人数
db.stu.aggregate(
{$group:{_id:"$gender",counter:{$sum:1}}}
{$project:{_id:0,counter:1}}
)
$sort用于将输入的文档排序后输出
使用实例如下:
#1.查询学生信息,按照年龄升序
db.stu.aggregate(
{$sort:{age:1}}
)
#2.查询男女生人生,按照人数降序
db.stu.aggregate(
{$group:{_id:"$gender",counter:{$sum:1}}}
{$sort:{counter:-1}}
)
使用实例如下:
#1.查询2条学生信息
db.stu.aggregate(
{$limit:2}
)
#2.查询从第三条开始的数据
db.stu.aggregate(
{$skip:3}
)
#3.统计男女生人数,按照人数升序,返回第二条数据
db.stu.aggregate(
{$group:{_id:"$gender"},counter:{$sum:1}},
{$sort:{counter:1}},
{$skip:1},
{$limit:1}
)
db.stu.aggregate({$unwind:{path:"size",preserveNullAndEmptyArrays:true}})
按照size字段进行拆分数据
插入数据:
for(i=0;i<100000;i++)
{db.t1.insert({name:"test"+i,age:i})}
创建索引前:
db.t1.find( {name:"test10000"} )
# 显示查询操作的详细信息
db.t1.find( {name:"test10000"} ).explain(executionStats"")
创建索引:
db.t1.ensureIndex({name:1})
创建索引后:
db.t1.find({name:"test10000"}).explain("executionStats")
默认情况下_id是集合的索引 查看方式 :db.集合名称.getIndexes()
db.集合名称.dropIndex( {“索引名称”:1} )
db.t1.dropIndex({name:1})
db.t1.getIndexes()
在默认情况下mongodb的索引域的值是可以相同的,创建唯一索引后,数据库会在插入数据的时候检查创建索引域的值是否存在,如果存在则不会插入该条数据,但是创建索引仅仅能够提高查询速度,同时降低数据库的插入速度。
9.6.1 添加唯一索引的语法:
db.集合名称.ensureIndex({字段名:1},{unique:true})
9.6.2 利用唯一索引进行数据去重
根据唯一索引指定的字段的值,如果相同,则无法插入数据
db.t1.ensureIndex({name:1},{unique:true})
db.t1.insert({name:"test10000"})
在进行数据去重的时候,可能用一个域来保证数据的唯一性,这个时候可以考虑建立复合索引来实现。
例如:抓全贴吧信息,如果把帖子的名字作为唯一索引对数据进行去重是不可取的,因为可能有很多帖子的名字相同。
建立复合索引的语法: