一、索引的作用
数据的存储在物理上是分散的,创建索引是将一块连续区域划分出来存放索引,加快系统查找数据的速度。
二、索引的种类
1、_id索引,默认创建
2、单键索引
db.集合名.createIndex({x:1})
3、多键索引
插入方式同单键索引,区别在于该字段包不包含数组,如包含则为多键索引
4、复合索引
db.集合名.createIndex({x:1,y:1})
5、过期索引,索引过期后,相应的数据会被删除,适合存储一些在一段时间后会失效的数据,如登录信息和存储日志等
//创建索引
db.集合名.createIndex({time:1},{expireAfterSeconds:30})
//使用索引
db.集合名.insert({time:new Date()})
补充说明:
(1)存储在过期索引字段的值必须是制定的时间类型,即ISODate或者ISODate数组,不能使用时间戳,否则过期删除机制失效
(2)如果指定了ISODate数组,按最先到设定时间的日期为删除日期,该设定的删除时间未必精确
(3)过期索引不能是复合索引
6、全文索引,mongodb中每个集合只允许创建一个全文索引,三种创建方式:
//单字段创建全文索引
db.集合名.createIndex({x:'test'})
//多字段段创建全文索引
db.集合名.createIndex({x:'test',y:'test'})
//对集合内所有字段创建全文索引
db.集合名.createIndex({'$**':'test'})
全文索引使用:
//全文搜索单个字符串
db.集合名.find({$text:{$search:"aa"}})
//全文搜索多个字符串,或关系
db.集合名.find({$text:{$search:"aa bb cc"}})
//全文搜索多个字符串,-为不包含
db.集合名.find({$text:{$search:"aa bb -cc"}})
//全文搜索多个字符串,与关系
db.集合名.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}})
//全文索引相似度排序,对结果按照从高分到低分排序
db.集合名.find({$text:{$search:"aa"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
全文索引限制:
(1)、每次查询,只能指定一个$text查询
(2)、$text查询不能出现在$nor查询中
(3)、查询中如果包含了$text,hint不再起作用
(4)、不支持中文
7、地理位置索引
(1)2d索引,用于存储和查找平面上的点
//2d索引的创建
db.集合名.createIndex({w:"2d"})
//2d索引的使用
//$near: 查询距离某个点最近的点,最多返回100个点
db.集合名.find({w:{$near:[1,1]}})
//$goWithin: 查询某个形状内的点
//查找距离[1,1]最大距离为10的点,不支持$minDistance
db.集合名.find({w:{$near:[1,1], $maxDistance:10}})
// 查找在矩形[0,0] [3,3]范围内的点
db.集合名.find({w:{$geoWithin:{$box:[[0,0],[3,3]]}}})
//查找以[0,0]为圆心半径为5的园内的点
db.集合名.find({w:{$geoWithin:{$center:[[0,0],5]}}})
//查找以[0,0],[1,1],[4,5],[6,6]为多边形内的点
db.集合名.find({w:{$geoWithin:{$polygon:[[0,0],[1,1],[4,5],[6,6]]}}})
//geoNear 查询(可以看做是$near查询的进化版本),它不仅支持 minDistance,而且它的返回结果多了一些数据,使用runCommand命令进行使用
db.runCommand({
getNear:<collection>, //指定数据集合
near:[x,y], //查询坐标
minDistance: //对2d索引无效,对2dsphere有效
maxDistance: //返回符合文档最多的数量
num:2 //返回的数量
})
//geoNear 查询返回结果
{
"results":[ //查询的结果
{
"dis": //查找到的数据与所指定查找的数据之间的距离
"obj":{} //查找到的数据
}
],
"stats":{ //查询的参数
"nscanned": //扫描了哪些数据
"objectsloaded":
"avgDistance": //平均距离
"maxDistance": //最大的距离
"time": //花费的时间
},
"ok":
}
(2)2dsphere索引
//创建方法
db.集合名.createIndex({w: '2dsphere'})
//使用方法
//2Dsphere位置表示方式:
//GeoJSON:描述一个点,一条直线,多边形等形状,可支持多边形交叉点等
//格式:{type:'', coordinates:[list]}
//GeoJSON非mongodb特有语法,不做详细介绍
三、索引属性
//param1是索引的值,param2是索引的属性。
db.集合名.createIndex({param1},{param2})
重要的索引属性:
1、名字
//指定名字,如该索引已经创建过了,指定名字不会覆盖原有名
db.集合名.createIndex({x:1,y:2,z:3},{name:"normal_index"})
//可用名字代替删除索引
db.集合名.dropIndex("normal_index")
2、唯一性
//唯一性
db.集合名.createIndex({x:1,y:1,z:1},{unique:true})
补充说明:
(1)、该情况下创建唯一性索引会报错,集合中已有部分文档某字段不重复,部分文档不包含某字段,则创建该字段的唯一性索引会报错,值为null也为重复,如再加入稀疏性属性则不报错
(2)、对多个字段创建唯一性索引,例如创建{x:1,y:1,z:1}索引,插入文档时{x:1,y:1,z:1}和{x:1,y:1,z:2}不违反唯一性规则,即他们的组合在当前集合下是唯一的即可
3、稀疏性
//指定索引是否稀疏,默认不稀疏
db.集合名.createIndex({},{sparse:true/false})
//稀疏索引的使用
//插入两个文档
db.集合名.insert({"m":1})
db.集合名.insert({"n":1})
//筛选出有m字段的文档,通过$exists可以判断字段是否存在
db.集合名.find({m:{$exists:true}})
//给这个文档的m字段创建一个稀疏索引, 第二条文档不存在m字段,所以不会创建这个索引
db.集合名.createIndex({m:1},{sparse:true})
//如果使用稀疏索引查找不存在稀疏索引字段的文档,mongodb则不会使用这个索引查找,例如:
//可以查到数据
db.集合名.find({m:{$exists:false}})
//但如果我们通过hint强制使用索引,就不会查到数据了,因为n上并没有m字段的索引
db.集合名.find({m:{$exists:false}}).hint("m_1")
4、是否定时删除(过期索引),索引种类里有介绍