简述
MongoDB中的索引其实类似于关系型数据库,都是为了提高查询和排序的效率的,并且实现原理也基本一致。由于集合中的键(字段)可以是普通数据类型,也可以是子文档。MongoDB可以在各种类型的键上创建索引。
索引
MongoDB的索引就是集合Collection里面的Key字段,一般默认都会有一个默认索引_id,这是唯一也是不能被删除的索引。也可以自己手动给某个索引指定唯一性:
db.testCollection.ensureIndex({...},unique:ture)
db.mycol.find().pretty()
说明:这是一段简单的索引的建立代码。
{
"_id":ObjectId(7df78ad8902c),
"a":"职友集",
"b":"广州",
"c":"招牌平台",
"d":"http://www.jonui.com",
"e":["php","java","adriod"],
"f":"50"
}
说明:这是一个典型的MongoDB集合文档的结构,其中我们可以看到集合有一个默认索引_id。
MongoDB索引分为7类:
[1]默认索引(_id索引):MongoDB有个默认的“_id”的键,他相当于“主键”的角色。集合创建后系统会自动创建一个索引在“_id”键上,它是默认索引,索引名叫“_id_”,是无法被删除的,_id值也是恒定不变的。
[2]单键索引:索引值为一个单一的值,比如字符串,更新日期等等。
[3]多建索引:索引值为多个值同时存在,例如数组。
[4]复合索引:单键索引和多建索引的结合。
[5]过期索引:在一段时间后会过期(自动销毁记录)的索引,适合用于处理用户登录信息等具有时间局限的记录过期处理(比较多的做法是Session或者cookie),对一些存储日志的过期处理等等用途。
[6]全文索引:主要用于搜索业务的索引,通过多种不同的查询方式和条件进行MongoDB全文索引,适合搜索引擎和站内搜索业务。
[7]地理位置索引:根据区间值进行范围索引查询,这种索引适合于当前越来越流行的打车软件查询人车位置时通过索引提升查询效率,还有网购点餐时查询距离自己范围内的餐厅地址等等。
注:索引的最终目标是提升查询效率和速度,索引不能过多,需要理性创建最适合的。
注:过期索引 :存储的字段值必须是指定的时间类型ISODate或者是ISODate数组,不能使用时间戳,否则索引会失效。
注:过期索引:记录自动销毁进程是每60S跑一次的后台程序,并不是很准时的自动程序。
注:过期索引:如果指定了ISODate数组,那么程序会自动吧数组内时间最早的那条记录销毁掉。
注:过期索引:过期索引不能被复合索引所引用。
注:全文索引:MongoDB全文索引目前不支持中文。
全文索引:在实际应用上,MongoDB的全文索引由于不支持中文索引,因此单单依靠MongoDB进行全文索引支持搜索业务的效率和成本是很高的,一般来讲业内是不建议使用MongoDB进行全文索引的,除非MongoDB官方能增加对中文索引的支持,不然,MongoDB更多的还是停留在数据仓库的角色。
注:全文索引:利用全文索引相似度可以实现对查询结果进行相似度排序,从而实现一个简单的小搜索相似度排序,类似于谷歌百度查询相似度排序。
创建:
db.testCollection.ensureIndex({"content":text})
查询:
db.testCollection.find({$test:{$search:"jobui.com"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
全文索引有四种查询方式:
(1)查询单条记录:
db.testCollection.find({$text:{$search:"aaa"}})
(2)用空格隔开实现多字段索引查询(或查询):
db.testCollection.find({$text:{$search:"aa bb cc"}})
(3)-可以使得查询结果不能含有指定字段:
db.testCollection.find({$test:{$search:"aa -bb"}})
(4)用”来实现“且”查询(并列查询):
db.testCollection.find({$text:{$search:"\"aa \"bb "}})
注:MongoDB全文索引每次查询只能指定一个$text查询
注:地理位置索引:查询距离某点的一定距离范围内的点;查找包含在某一区域所有点。
注:地理位置索引:有两个子分类。
(1)2D索引:平面地理位置索引
(2)2Dsphere索引:球面地理位置索引
创建:
(1)2D索引:
db.a.ensureIndex({w:"2d"})
//*位置表示方式:经纬度[经度,纬度],取值范围:经度[-180,180]纬度[-90,90]
(2)2Dsphere索引:
db.a.ensureIndex({w:"2dsphere"})
//*位置表示方式:GeoJSON描述点、线、多边形,格式:{type:"",coordinates:[]},支持$minDistance,$maxDistance
查询:
(1)2D索引:
$Near查询:查询距离某个点最近的点。
例:
db.a.find({w:{$near:[1,1], $maxDistance:10}})
//*查询在点[1,1]距离最近的10个点。
$geoWithin查询:查询某个形状内的点。
例1:
db.a.find({w:{$geowithin:{$box:[0,0], [3,3]}}})
//*查询在左边界[0,0],右边界[3,3]的矩形范围内的所有点。
例2:
db.a.find({w:{$geowithin:{$center:[[0,0], 5]}}})
//*查询在[0,0]为圆心,半径为5的圆形区域内的所有点。
例3:
db.a.find({w:{$geowithin:{$polygon:[[0,0], [1,2], [2,5], [6,1]]}}})
//*查询在多个坐标点组成的多边形范围内的所有点。
$geoNear查询:查询相近的点的数据。
例:
db.command({$geoNear:"a", near:[1,2], maxDistance:10, num:1})
(2)2Dsphere索引:略。
注:MongoDB自带的库状态管理工具Mongostat:这个工具可以查看当前MongoDB的数据读取和索引命中情况:
命令:./mongostat -h 127.0.0.1:8080 可以查看MongoDB状态信息。
其中请关注这些字段所给我们返回的信息:
qr : 读队列情况(实时查询MongoDB情况)
qw : 写队列情况(实时写入MongoDB情况)
idx miss : 索引命中情况
注:在find()后面加入explain()可以查看查询的详细信息