Mongodb--索引(转载)
原文转载自:https://www.cnblogs.com/wyy1234/p/11032163.html
1 mongoDB索引的管理
db.userinfos.insertMany([
{_id:1, name: "张三", age: 23,level:10, ename: { firstname: "san", lastname: "zhang"}, roles: ["vip","gen" ]},
{_id:2, name: "李四", age: 24,level:20, ename: { firstname: "si", lastname: "li"}, roles:[ "vip" ]},
{_id:3, name: "王五", age: 25,level:30, ename: { firstname: "wu", lastname: "wang"}, roles: ["gen","vip" ]},
{_id:4, name: "赵六", age: 26,level:40, ename: { firstname: "liu", lastname: "zhao"}, roles: ["gen"] },
{_id:5, name: "田七", age: 27, ename: { firstname: "qi", lastname: "tian"}, address:'北京' },
{_id:6, name: "周八", age: 28,roles:["gen"], address:'上海' }
]);
索引的增删改查还是十分简单的,我们看一下索引管理的几个方法:(在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法)
//创建索引,值1表示正序排序,-1表示倒序排序
db.userinfos.createIndex({age:-1}) //查看userinfos中的所有索引
db.userinfos.getIndexes() //删除特定一个索引
db.userinfos.dropIndex({name:1,age:-1})
//删除所有的索引(主键索引_id不会被删除)
db.userinfos.dropIndexes() //如果我们要修改一个索引的话,可以先删除索引然后在重新添加。
2 mongoDB中常用的索引类型
1 单键索引
单键索引(Single Field Indexes)顾名思义就是单个字段作为索引列,mongoDB的所有collection默认都有一个单键索引_id,我们也可以对一些经常作为过滤条件的字段设置索引,如给age字段添加一个索引,语法十分简单:
//给age字段添加升序索引
db.userinfos.createIndex({age:1})
其中{age:1}中的1表示升序,如果想设置倒序索引的话使用 db.userinfos.createIndex({age:-1}) 即可。我们通过explain()方法查看查询计划,如下图,看到查询age=23的document时使用了索引,如果没有使用索引的话stage=COLLSCAN。

因为document的存储是bson格式的,我们也可以给内置对象的字段添加索引,或者将整个内置对象作为一个索引,语法如下:
//1.内嵌对象的某一字段作为索引
//在ename.firstname字段上添加索引
db.userinfos.createIndex({"ename.firstname":1})
//使用ename.firstname字段的索引查询
db.userinfos.find({"ename.firstname":"san"}) //2.整个内嵌对象作为索引
//给整个ename字段添加索引
db.userinfos.dropIndexes()
//使用ename字段的索引查询
db.userinfos.createIndex({"ename":1})
2 复合索引
复合索引(Compound Indexes)指一个索引包含多个字段,用法和单键索引基本一致。使用复合索引时要注意字段的顺序,如下添加一个name和age的复合索引,name正序,age倒序,document首先按照name正序排序,然后name相同的document按age进行倒序排序。mongoDB中一个复合索引最多可以包含32个字段。
//添加复合索引,name正序,age倒序
db.userinfos.createIndex({"name":1,"age":-1})
//过滤条件为name,或包含name的查询会使用索引(索引的第一个字段)
db.userinfos.find({name:'张三'}).explain()
db.userinfos.find({name:"张三",level:10}).explain()
db.userinfos.find({name:"张三",age:23}).explain() //查询条件为age时,不会使用上边创建的索引,而是使用的全表扫描
db.userinfos.find({age:23}).explain()
执行查询时查询计划如下:

3 多键索引
多键索引(mutiKey Indexes)是建在数组上的索引,在mongoDB的document中,有些字段的值为数组,多键索引就是为了提高查询这些数组的效率。看一个例子:准备测试数据,classes集合中添加两个班级,每个班级都有一个students数组,如下:
db.classes.insertMany([
{
"classname":"class1",
"students":[{name:'jack',age:20},
{name:'tom',age:22},
{name:'lilei',age:25}]
},
{
"classname":"class2",
"students":[{name:'lucy',age:20},
{name:'jim',age:23},
{name:'jarry',age:26}]
}]
)
为了提高查询students的效率,我们使用 db.classes.createIndex({'students.age':1}) 给students的age字段添加索引,然后使用索引,如下图:

4 哈希索引
哈希索引(hashed Indexes)就是将field的值进行hash计算后作为索引,其强大之处在于实现O(1)查找,当然用哈希索引最主要的功能也就是实现定值查找,对于经常需要排序或查询范围查询的集合不要使用哈希索引。

3 mongoDB中常用的索引属性
1 唯一索引
唯一索引(unique indexes)用于为collection添加唯一约束,即强制要求collection中的索引字段没有重复值。添加唯一索引的语法:
//在userinfos的name字段添加唯一索引
db.userinfos.createIndex({name:1},{unique:true})
看一个使用唯一索引的栗子:

2 局部索引
局部索引(Partial Indexes)顾名思义,只对collection的一部分添加索引。创建索引的时候,根据过滤条件判断是否对document添加索引,对于没有添加索引的文档查找时采用的全表扫描,对添加了索引的文档查找时使用索引。使用方法也比较简单:

//userinfos集合中age>25的部分添加age字段索引
db.userinfos.createIndex(
{age:1},
{ partialFilterExpression: {age:{$gt: 25 }}}
)
//查询age<25的document时,因为age<25的部分没有索引,会全表扫描查找(stage:COLLSCAN)
db.userinfos.find({age:23})
//查询age>25的document时,因为age>25的部分创建了索引,会使用索引进行查找(stage:IXSCAN)
db.userinfos.find({age:26})

当查询age=23的记录时,stage=COLLSCAN,当查询age=26的记录时,使用了索引,如下:

2 稀疏索引
稀疏索引(sparse indexes)在有索引字段的document上添加索引,如在address字段上添加稀疏索引时,只有document有address字段时才会添加索引。而普通索引则是为所有的document添加索引,使用普通索引时如果document没有索引字段的话,设置索引字段的值为null。
稀疏索引的创建方式如下,当document包含address字段时才会创建索引:
//创建在address上创建稀疏索引
db.userinfos.createIndex({address:1},{sparse:true})
看一个使用稀疏索引的栗子:

4 TTL索引
TTL索引(TTL indexes)是一种特殊的单键索引,用于设置document的过期时间,mongoDB会在document过期后将其删除,TTL非常容易实现类似缓存过期策略的功能。我们看一个使用TTL索引的栗子:
//添加测试数据
db.logs.insertMany([
{_id:1,createtime:new Date(),msg:"log1"},
{_id:2,createtime:new Date(),msg:"log2"},
{_id:3,createtime:new Date(),msg:"log3"},
{_id:4,createtime:new Date(),msg:"log4"}
])
//在createtime字段添加TTL索引,过期时间是120s
db.logs.createIndex({createtime:1}, { expireAfterSeconds: 120 }) //logs中的document在创建后的120s后过期,会被mongoDB自动删除
注意:TTL索引只能设置在date类型字段(或者包含date类型的数组)上,过期时间为字段值+exprireAfterSeconds;document过期时不一定就会被立即删除,因为mongoDB执行删除任务的时间间隔是60s;capped Collection不能设置TTL索引,因为mongoDB不能主动删除capped Collection中的document。
Mongodb--索引(转载)的更多相关文章
- MongoDB(索引及C#如何操作MongoDB)(转载)
MongoDB(索引及C如何操作MongoDB) 索引总概况 db.test.ensureIndex({"username":1})//创建索引 db.test.ensureInd ...
- MongoDB 索引类型介绍
转载请注明出处: 目录 1.单字段索引 2.复合索引 3.多key索引 4.其他类型索引 5.索引额外属性 6.MongoDB 索引相关的常用sql命令 MongoDB 支持多种类型的索引,包括单字段 ...
- MongoDB 索引原理与索引优化
转载请注明出处: 1.MongoDB索引 索引通常能够极大的提高查询的效率, 如果没有索引, MongoDB 在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录.这种扫描全集合的查询效率 ...
- [DataBase] MongoDB (7) MongoDB 索引
MongoDB 索引 1. 建立索引 唯一索引db.passport.ensureIndex( {"loginname": 1}, {"unique": tru ...
- MongoDB索引介绍
MongoDB中的索引其实类似于关系型数据库,都是为了提高查询和排序的效率的,并且实现原理也基本一致.由于集合中的键(字段)可以是普通数据类型,也可以是子文档.MongoDB可以在各种类型的键上创建索 ...
- MongoDB索引(一)
原文地址 一.介绍 我们已经很清楚索引会提高查询效率.如果没有索引,MongoDB必须对全部集合进行扫描,即,扫描集合中每条文档以选择那些符合查询条件的文档.对查询来说如果存在合适的索引,则Mongo ...
- MongoDB 索引篇
MongoDB 索引篇 索引的简介 索引可以加快查询的速度,但是过多的索引或者规范不好的索引也会影响到查询的速度.且添加索引之后的对文档的删除,修改会比以前速度慢.因为在进行修改的时候会对索引进行更新 ...
- MongoDB索引的种类与使用
一:索引的种类 1:_id索引:是绝大多数集合默认建立的索引,对于每个插入的数据,MongoDB都会自动生成一条唯一的_id字段2:单键索引: 1.单键索引是最普通的索引 2.与_id索引不同,单键索 ...
- MongoDB索引,性能分析
索引的限制: 索引名称不能超过128个字符 每个集合不能超过64个索引 复合索引不能超过31列 MongoDB 索引语法 db.collection.createIndex({ <field&g ...
- MongoDB索引原理
转自:http://www.mongoing.com/archives/2797 为什么需要索引? 当你抱怨MongoDB集合查询效率低的时候,可能你就需要考虑使用索引了,为了方便后续介绍,先科普下M ...
随机推荐
- Python数字加密方法:建立从0到9的数字序列,将输入的数字数据,每个数字在数字序列中循环右移2位,输出该数据对应的汉字大写形式。
数字加密方法:建立从0到9的数字序列,将输入的数字数据,每个数字在数字序列中循环右移2位,输出该数据对应的汉字大写形式. 样例1:输入123,输出三四五 样例2:输入985,输出一零七 def Slo ...
- java笔记——面向对象
1.概述:面向对象是基于面向过程的编程思想 举例:把大象装进冰箱 2.开发:不断的创建对象,使用对象,指挥对象做事情 3.面向对象特征:封装 , 继承 , 多态 4.类和对象的关系: 类是一组相关的属 ...
- 在路上---学习篇(一)Python 数据结构和算法 (4) --希尔排序、归并排序
独白: 希尔排序是经过优化的插入排序算法,之前所学的排序在空间上都是使用列表本身.而归并排序是利用增加新的空间,来换取时间复杂度的减少.这俩者理念完全不一样,注定造成的所消耗的时间不同以及空间上的不同 ...
- DDD学习与感悟——总是觉得自己在CRUD怎么办?
一.DDD是什么? DDD全名叫做Domins drives Design:领域驱动设计.再说的通俗一点就是:通过领域建模的方式来实现软件设计. 问题来了:什么是软件设计?为什么要进行软件设计? 软件 ...
- jdk9模块化
JDK 9是Java开发语言的一个重大版本.其中最令人兴奋的新特性之一是模块化系统.模块化系统提出了一种新的代码组织方式,它可以帮助开发人员更好地组织和管理代码,从而使Java应用程序更加可维护.可扩 ...
- [ARC165E] Random Isolation
Problem Statement There is a tree with $N$ vertices numbered $1$ to $N$. The $i$-th edge connects ve ...
- pinia入门案例-获取频道分类列表并渲染
使用pinia的action异步获取频道分类列表数据并渲染到页面中. 接口: GET请求,http://geek.itheima.net/v1_0/channels store/channel.js ...
- X410的白嫖方案
微软商店下的x410要收费试用也就几天,记录白嫖方案.配置和使用跳转到上一篇文章:Windows下使用图形化的Havoc C2 编译运行 GitHub上start最多的是这个仓库,但是已经很久没有维护 ...
- MinIO FTP 断点续传
MinIO FTP 断点续传 对于minio来说,使用minio官方的Java SDK和开启FTP都是不支持断点续传的.对于要实现http接口的断点续传,可以通过调用Amazon S3 REST AP ...
- POJ 2609 DP 双队列DP
POJ 2609 DP 双队列DP 题意 给出队列容量与一组数,并且我们有两个这样容量的空队列,要求我们按照次序把数装进两个队列中,输出最多能装多少以及每个数装进哪个队列. 思路 由于按照次序来装,不 ...