快速掌握mongoDB(三)——mongoDB的索引详解
1 mongoDB索引的管理
db.userinfos.insertMany([
{_id:, name: "张三", age: ,level:, ename: { firstname: "san", lastname: "zhang"}, roles: ["vip","gen" ]},
{_id:, name: "李四", age: ,level:, ename: { firstname: "si", lastname: "li"}, roles:[ "vip" ]},
{_id:, name: "王五", age: ,level:, ename: { firstname: "wu", lastname: "wang"}, roles: ["gen","vip" ]},
{_id:, name: "赵六", age: ,level:, ename: { firstname: "liu", lastname: "zhao"}, roles: ["gen"] },
{_id:, name: "田七", age: , ename: { firstname: "qi", lastname: "tian"}, address:'北京' },
{_id:, name: "周八", age: ,roles:["gen"], address:'上海' }
]);
索引的增删改查还是十分简单的,我们看一下索引管理的几个方法:
//创建索引,值1表示正序排序,-1表示倒序排序
db.userinfos.createIndex({age:-}) //查看userinfos中的所有索引
db.userinfos.getIndexes() //删除特定一个索引
db.userinfos.dropIndex({name:,age:-})
//删除所有的索引(主键索引_id不会被删除)
db.userinfos.dropIndexes() //如果我们要修改一个索引的话,可以先删除索引然后在重新添加。
2 mongoDB中常用的索引类型
1 单键索引
单键索引(Single Field Indexes)顾名思义就是单个字段作为索引列,mongoDB的所有collection默认都有一个单键索引_id,我们也可以对一些经常作为过滤条件的字段设置索引,如给age字段添加一个索引,语法十分简单:
//给age字段添加升序索引
db.userinfos.createIndex({age:})
其中{age:1}中的1表示升序,如果想设置倒序索引的话使用 db.userinfos.createIndex({age:-}) 即可。我们通过explain()方法查看查询计划,如下图,看到查询age=23的document时使用了索引,如果没有使用索引的话stage=COLLSCAN。
因为document的存储是bson格式的,我们也可以给内置对象的字段添加索引,或者将整个内置对象作为一个索引,语法如下:
//1.内嵌对象的某一字段作为索引
//在ename.firstname字段上添加索引
db.userinfos.createIndex({"ename.firstname":})
//使用ename.firstname字段的索引查询
db.userinfos.find({"ename.firstname":"san"}) //2.整个内嵌对象作为索引
//给整个ename字段添加索引
db.userinfos.dropIndexes()
//使用ename字段的索引查询
db.userinfos.createIndex({"ename":})
2 复合索引
复合索引(Compound Indexes)指一个索引包含多个字段,用法和单键索引基本一致。使用复合索引时要注意字段的顺序,如下添加一个name和age的复合索引,name正序,age倒序,document首先按照name正序排序,然后name相同的document按age进行倒序排序。mongoDB中一个复合索引最多可以包含32个字段。
//添加复合索引,name正序,age倒序
db.userinfos.createIndex({"name":,"age":-})
//过滤条件为name,或包含name的查询会使用索引(索引的第一个字段)
db.userinfos.find({name:'张三'}).explain()
db.userinfos.find({name:"张三",level:}).explain()
db.userinfos.find({name:"张三",age:}).explain() //查询条件为age时,不会使用上边创建的索引,而是使用的全表扫描
db.userinfos.find({age:}).explain()
执行查询时查询计划如下:
3 多键索引
多键索引(mutiKey Indexes)是建在数组上的索引,在mongoDB的document中,有些字段的值为数组,多键索引就是为了提高查询这些数组的效率。看一个栗子:准备测试数据,classes集合中添加两个班级,每个班级都有一个students数组,如下:
db.classes.insertMany([
{
"classname":"class1",
"students":[{name:'jack',age:},
{name:'tom',age:},
{name:'lilei',age:}]
},
{
"classname":"class2",
"students":[{name:'lucy',age:},
{name:'jim',age:},
{name:'jarry',age:}]
}]
)
为了提高查询students的效率,我们使用 db.classes.createIndex({'students.age':}) 给students的age字段添加索引,然后使用索引,如下图:
4 哈希索引
哈希索引(hashed Indexes)就是将field的值进行hash计算后作为索引,其强大之处在于实现O(1)查找,当然用哈希索引最主要的功能也就是实现定值查找,对于经常需要排序或查询范围查询的集合不要使用哈希索引。
3 mongoDB中常用的索引属性
1 唯一索引
唯一索引(unique indexes)用于为collection添加唯一约束,即强制要求collection中的索引字段没有重复值。添加唯一索引的语法:
//在userinfos的name字段添加唯一索引
db.userinfos.createIndex({name:},{unique:true})
看一个使用唯一索引的栗子:
2 局部索引
局部索引(Partial Indexes)顾名思义,只对collection的一部分添加索引。创建索引的时候,根据过滤条件判断是否对document添加索引,对于没有添加索引的文档查找时采用的全表扫描,对添加了索引的文档查找时使用索引。使用方法也比较简单:
//userinfos集合中age>25的部分添加age字段索引
db.userinfos.createIndex(
{age:},
{ partialFilterExpression: {age:{$gt: }}}
)
//查询age<25的document时,因为age<25的部分没有索引,会全表扫描查找(stage:COLLSCAN)
db.userinfos.find({age:})
//查询age>25的document时,因为age>25的部分创建了索引,会使用索引进行查找(stage:IXSCAN)
db.userinfos.find({age:})
当查询age=23的记录时,stage=COLLSCAN,当查询age=26的记录时,使用了索引,如下:
2 稀疏索引
稀疏索引(sparse indexes)在有索引字段的document上添加索引,如在address字段上添加稀疏索引时,只有document有address字段时才会添加索引。而普通索引则是为所有的document添加索引,使用普通索引时如果document没有索引字段的话,设置索引字段的值为null。
稀疏索引的创建方式如下,当document包含address字段时才会创建索引:
//创建在address上创建稀疏索引
db.userinfos.createIndex({address:},{sparse:true})
看一个使用稀疏索引的栗子:
4 TTL索引
TTL索引(TTL indexes)是一种特殊的单键索引,用于设置document的过期时间,mongoDB会在document过期后将其删除,TTL非常容易实现类似缓存过期策略的功能。我们看一个使用TTL索引的栗子:
//添加测试数据
db.logs.insertMany([
{_id:,createtime:new Date(),msg:"log1"},
{_id:,createtime:new Date(),msg:"log2"},
{_id:,createtime:new Date(),msg:"log3"},
{_id:,createtime:new Date(),msg:"log4"}
])
//在createtime字段添加TTL索引,过期时间是120s
db.logs.createIndex({createtime:}, { expireAfterSeconds: }) //logs中的document在创建后的120s后过期,会被mongoDB自动删除
注意:TTL索引只能设置在date类型字段(或者包含date类型的数组)上,过期时间为字段值+exprireAfterSeconds;document过期时不一定就会被立即删除,因为mongoDB执行删除任务的时间间隔是60s;capped Collection不能设置TTL索引,因为mongoDB不能主动删除capped Collection中的document。
小结
本节介绍了mongoDB中常用的索引和索引属性,索引对提升数据检索的速度十分重要,在数据量比较大的时候一般都要在collection上建立索引。mongoDB提供的索引种类很丰富,总会有几种适用于我们的业务,除了上边介绍的索引外,mongoDB还支持text index和一些地理位置相关的索引,这里不再介绍,有兴趣的小伙伴可以到官网 研究下。如果文中有错误的话,希望大家可以指出,我会及时修改,谢谢。
快速掌握mongoDB(三)——mongoDB的索引详解的更多相关文章
- Solr系列三:solr索引详解(Schema介绍、字段定义详解、Schema API 介绍)
一.Schema介绍 1. Schema 是什么? Schema:模式,是集合/内核中字段的定义,让solr知道集合/内核包含哪些字段.字段的数据类型.字段该索引存储. 2. Schema 的定义方式 ...
- Oracle索引详解
Oracle索引详解(二) --索引分类 Oracle 提供了大量索引选项.知道在给定条件下使用哪个选项对于一个程序的性能来说非常重要.一个错误的选择可能会引发死锁,并导致数据库性能急剧下降或进程 ...
- Spring Boot 2.x 快速入门(下)HelloWorld示例详解
上篇 Spring Boot 2.x 快速入门(上)HelloWorld示例 进行了Sprint Boot的快速入门,以实际的示例代码来练手,总比光看书要强很多嘛,最好的就是边看.边写.边记.边展示. ...
- spring事务详解(三)源码详解
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...
- 【详细解析】MySQL索引详解( 索引概念、6大索引类型、key 和 index 的区别、其他索引方式)
[详细解析]MySQL索引详解( 索引概念.6大索引类型.key 和 index 的区别.其他索引方式) MySQL索引的概念: 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分 ...
- MySQL 联合索引详解
MySQL 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c ...
- Hadoop集群搭建安装过程(三)(图文详解---尽情点击!!!)
Hadoop集群搭建安装过程(三)(图文详解---尽情点击!!!) 一.JDK的安装 安装位置都在同一位置(/usr/tools/jdk1.8.0_73) jdk的安装在克隆三台机器的时候可以提前安装 ...
- Linux防火墙iptables学习笔记(三)iptables命令详解和举例[转载]
Linux防火墙iptables学习笔记(三)iptables命令详解和举例 2008-10-16 23:45:46 转载 网上看到这个配置讲解得还比较易懂,就转过来了,大家一起看下,希望对您工作能 ...
- python selenium 三种等待方式详解[转]
python selenium 三种等待方式详解 引言: 当你觉得你的定位没有问题,但是却直接报了元素不可见,那你就可以考虑是不是因为程序运行太快或者页面加载太慢造成了元素不可见,那就必须要加等待 ...
- Window下PHP三种运行方式图文详解,window下的php是不是单进程的?
Window下PHP三种运行方式图文详解,window下的php是不是单进程的? PHP运行目前为止主要有三种方式: a.以模块加载的方式运行,初学者可能不容易理解,其实就是将PHP集成到Apache ...
随机推荐
- SQL Server 中心订阅模型(多发布单订阅)
原文:SQL Server 中心订阅模型(多发布单订阅) 大多数SQL Server 复制拓扑都是基于中心发布模型,它是由一个发布复制到一个或者多个订阅.另一个复制模型是中心订阅模型,它使用事务复制由 ...
- Android零基础入门第27节:正确使用padding和margin
原文:Android零基础入门第27节:正确使用padding和margin 前面两期我们学习了LinearLayout线性布局的方向.填充模型.权重和对齐,那么本期我们来学习LinearLayout ...
- vmstat命令浅析
vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况.这个命令是我查看Linux/Unix最 ...
- 【Python】:拓展Queue实现有序不重复队列
最近手头有个需求是这样的,定期检查数据库获取失败任务并且进行重启.最早想到的是添加一个生产者&&消费者队列,但是发现很多棘手的问题. 1.重启任务是调用的一个shell脚本然后在脚本中 ...
- 去除文件属性(使用SetFileAttributes API函数)
FILE_ATTRIBUTE_ARCHIVE 文件存档(备份或移动时会对文件做标记).FILE_ATTRIBUTE_ENCRYPTED 加密(对文件来说是内容加密,对目录来说是对将来新建的文件默认为加 ...
- 从零开始人工智能AI(一)-k-nn-矩阵
参考资料: https://baike.baidu.com/item/%E7%9F%A9%E9%98%B5/18069?fr=aladdin http://blog.csdn.net/c4064957 ...
- ACM竞赛中的魔方问题专题(不定时更新)
魔方有6个面,有24中不同的旋转方式: 一般有两种方法: (一):以1面为顶面,向右旋转0,90,180,270度 以2面为顶面,向右旋转0,90,180,270度 ... 以6面为顶面,向右旋转0, ...
- HTML连载7-表单练习
昨天因为晚上有事情,未更新,但是今天中午发也不晚,因为是同一天只是时间早晚而已,因此今日傍晚还将更新一次,废话不多说. 1.表单的综合练习,我们要创建一个综合的注册页面.运用到我们前面所学的所有知识. ...
- ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用
在前面几篇随笔介绍了我对ABP框架的改造,包括对ABP总体的介绍,以及对各个业务分层的简化,Web API 客户端封装层的设计,使得我们基于ABP框架的整体方案越来越清晰化, 也越来越接近实际的项目开 ...
- 设计模式之装饰器模式(decorator pattern)
装饰器模式主要对现有的类对象进行包裹和封装,以期望在不改变类对象及其类定义的情况下,为对象添加额外功能.是一种对象结构型模式.需要注意的是,该过程是通过调用被包裹之后的对象完成功能添加的,而不是直接修 ...