Mongodb数据库聚合操作及索引(四)

8.mongodb的聚合操作

8.1 mongodb的聚合是什么

聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。

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

8.2 mongodb的常用管道和表达式

8.2.1 常用管道命令

在mongodb中,文档处理完毕后,通过管道进行下一次处理 常用管道命令如下:

  • $group:将集合中的文档分组,可用于统计结果
  • $match:过滤数据,只输出符合条件的文档
  • $project:修改文档的结果,如重命名、增加、删除字段、创建计算结果
  • $sort:将输入文档排序后输出
  • $limit:限制聚合管道返回的文档数
  • $skip:跳过指定数量的文档,并返回余下的文档

8.2.2 常用表达式

表达式:处理输入文档并输出 语法: 表达式:"$列名" 常用表达式:

  • s u m : 计 算 综 合 , sum:计算综合, sumsum:1 表示以一倍计数
  • $avg:计算平均值
  • $min:获取最小值
  • $max:获取最大值
  • $push:在结果文档中插入值到一个数组中
8.3 管道命令之 $group

8.3.1 按照某个字段进行分组

$group是所有聚合命令中用的最多的一个命令,用来将集合中的文档分组,可用于统计结果

使用实例如下:

db.stu.aggregate(
	{$group:
     
     	_id:"$gender",
     	counter:{$sum:1}
        
    }

)

注意点:

  • db.db_name.aggregate是语法,所有的管道命令都需要写在其中
  • _id表示分组的依据,按照哪个字段进行分组,比如使用$gender表示选择这个字段进行分组
  • $sum:1 表示把每条数据作为1进行统计,统计的是该分组下面的数据的条数

8.3.2 group by null

当我们需要统计整个文档的时候,$group的另一种用途就是把整个文档分为一组进行统计

使用实例如下:

db.stu.aggregate(
	{$group:
    	{
            _id:null,
            counter:{$num:1}
        }
    
    }
)

注意点:

  • _id:null表示不指定分组的字段,即统计整个文档,此时获取的counter表示整个文档的个数

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"}
        }
    }
)
8.4管道命令之$match

m a t c h 用 于 进 行 数 据 的 过 滤 , 是 能 够 在 聚 合 操 作 中 使 用 的 命 令 , 和 f i n d 区 别 在 于 match用于进行数据的过滤,是能够在聚合操作中使用的命令,和find区别在于 match使findmatch操纵可以把结果交给下一个管道处理,而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}}
    }
)
8.5管道命令之$project

$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}}
)
8.6 管道命令之$sort

$sort用于将输入的文档排序后输出

使用实例如下:

#1.查询学生信息,按照年龄升序
db.stu.aggregate(
	{$sort:{age:1}}
)
#2.查询男女生人生,按照人数降序
db.stu.aggregate(
	{$group:{_id:"$gender",counter:{$sum:1}}}
    {$sort:{counter:-1}}
)
8.7 管道命令之 l i m i t 和 limit和 limitskip
  • $limit 限制返回数据的条数
  • $skip 跳过指定的文档书,并返回剩下的文档数
  • 同时使用时先skip再使用limit

使用实例如下:

#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}
)

8.8 拆分管道
db.stu.aggregate({$unwind:{path:"size",preserveNullAndEmptyArrays:true}})

按照size字段进行拆分数据

9.mongodb的索引

9.1 为什么mongodb需要创建索引
  • 加快查询速度
  • 进行数据的去重
9.2 mongodb创建简单的索引方法
  • db.集合名称.ensureIndex( {属性:1} )
    • 1表示升序,-1表示降序
9.3 创建索引前后查询速度对比
  • 插入数据:

    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")
    
9.4索引的查看

默认情况下_id是集合的索引 查看方式 :db.集合名称.getIndexes()

9.5删除索引
  • db.集合名称.dropIndex( {“索引名称”:1} )

    db.t1.dropIndex({name:1})
    db.t1.getIndexes()
    
9.6 mongodb创建唯一索引

在默认情况下mongodb的索引域的值是可以相同的,创建唯一索引后,数据库会在插入数据的时候检查创建索引域的值是否存在,如果存在则不会插入该条数据,但是创建索引仅仅能够提高查询速度,同时降低数据库的插入速度。

9.6.1 添加唯一索引的语法:

db.集合名称.ensureIndex({字段名:1},{unique:true})

9.6.2 利用唯一索引进行数据去重

根据唯一索引指定的字段的值,如果相同,则无法插入数据

db.t1.ensureIndex({name:1},{unique:true})
db.t1.insert({name:"test10000"})
9.7 mongodb创建复合索引

在进行数据去重的时候,可能用一个域来保证数据的唯一性,这个时候可以考虑建立复合索引来实现。

例如:抓全贴吧信息,如果把帖子的名字作为唯一索引对数据进行去重是不可取的,因为可能有很多帖子的名字相同。

建立复合索引的语法:

  • db.集合名字.ensureIndex({字段1:1,字段2:1})
9.8 建立索引注意点
  • 根据需要选择是否需要建立唯一索引
  • 索引字段是升序还是降序在单个索引的情况下不影响查询效率,但是带复合索引的条件下会有影响
  • 数据量巨大并且数据库的读出操作非常频繁的时候不需要创建索引,如果写入操作非常频繁,创建索引会影响写入速度。
  • 例如:在进行查询的时候如果字段1需要升序的方式排序输出,字段2需要降序的方式排序输出,那么此时复合索引的建立需要把字段1设置为1,字段2设置为-1

你可能感兴趣的:(mongodb)