MongoDB索引
MongoDB索引的介绍:
简介
索引就是用来加速查询的。数据库索引与书籍的索引类似:有了索引就不需要翻遍整本书,数据库则可以直接在索引中査找,使得查找速度能提高几个数量级。在索引中找到条目以后,就可以直接跳转到目标文档的位置。让这个比喻走个极端,可以说创建数据库索引就像确定如何组织书的索引一样。但你的优势是知道今后会做何种査询,以及哪些内容需要快速査找。索引能够提升查询效率.没有索引,MongoDB必须扫描集合中的所有文档才能找到匹配查询语句文档,索引是一种特殊的数据结构,将一小块数据集保存为容易遍历的形式.索引能够存储某种特殊字段或字段的值,按照索引指定的方式可以将字段值进行排序,对于添加的每一个索引,每一次插入更新,删除都将消耗更多的时间,因为数据发生改变的时候不仅仅是更新文档,还有更新集合上的所有索引.MongoDB限制每个集合上的最多有64个索引,使用索引键对文档进行排序时可以提升排序效率,索引时按照一定顺序排列的,,索引才有效果,索引类型有很多包括 单字段索引、复合索引、多支索引、地理空间索引、文本索引等等.
创建索引
|
|
keys 希望创建索引的名称和排序方式1表示升序,-1表示降序排列,格式{key:1, key-1}如果时基于多个索引键进行排序,要特别注意索引的排序方向,相同的排序方向可以提升排序效率,单个键排序时没有影响。
options:可选参数,表示建立索引的设置:
参数 | 数据类型 | 默认值 | 功能 |
---|---|---|---|
background | Boolean | false | 后台建立索引,以便创建索引时不阻止其他数据库活动 |
unique | Boolean | false | 创建唯一索引 |
name | String | 指定索引名称,如果未指定,MongoDB会生成一个索引字段的名称和排序顺序串联 | |
partialFilterExpression | document | 如果指定MongoDB指挥满足过滤表达式的记录 | |
sparse | Boolean | false | 对文档中不的存在的字段数据不启用索引 |
expireAfterSeconds | integer | 指定索引的过期时间 | |
storageEngine | document类型允许用户配置索引的额存储引擎 |
删除索引
方式一
删除当前集合中的所有索引(_id上默认索引除外)
|
|
方式二
|
|
在索引上找到条目之后,就可以直接跳到目标文档的位置
在user中有5个文档,其中存储信息如下
|
|
如果有个查询
|
|
这个时候需要遍历所有的文档,查询所有的文档,根据位置信息读出文档,对比age字段是否为18。当然入股偶只有5个文档,全表扫描的开销并不大,简单如果集合文档数量到百万,千万或者上亿的时候,对集合进行去哪表扫描的开销时非常大的,一个查询耗费数十秒甚至几分钟都可能。
如果想加速
|
|
可以对user表的age字段孙银
按照age字段创建升序索引
|
|
建立索引之后,MongoDB会额外存储一份按照ae字段升序排序的索引数据,索引通常采用类似于btree的结构持久化存储
以保证从索引里快速找出某个age值对应的位置信息,然后根据位置信息就能读取出对应的文档。
简单的说,索引就是将文档按照某个(或者某些)字段顺序组织起来,以便能根据该字段高效的查询。
唯一索引
MongoDB默认会为插入的文档生成_id字段(如果应用本身没有指定该字端),_id时文档的唯一表示,为了保证能够根据文档id快速查询文档,MongoDB默认会为集合创建_id的字段索引,唯一索引可以确保集合的每一个文档的指定键都有唯一值。如果想保留文档的“name”键都有不一样的值,创建一个唯一索引就好了:
|
|
由于insert并不健查文档时否查如果,为了避免插入的文档包含与唯一键重复i的值,可能要用安全插入才能满足要求。这样,在插入文档时会看到存在重复键的错误的提示。
消除重复
当为已有的索引创建索引,可能有些之已经有重复了。这时候创建所以会失败,我们希望将所有包含重复值的文档都删掉。dropDups选项就可以奥六发现的第一个文档,二删除接下来有重复的键值文档,如“name”键重复的索引值
|
|
通常做开发不建议删除操作。
复合唯一索引
符合索引就是建立在多个字段上的索引 例如:
|
|
上述符合索引由“age” “name” 组成的索引
复合唯一索引就是允许单个的键的值相同,但是所有键的组合之组合起来的不同索引
|
|
所有的“age”键都相同,但是“name“键的值不同,如果尝试再次插入
|
|
数据库会体时存在重复键的错误。
索引管理
索引的元信息存储在每个数据库的system.indexes集合中。这是一个保留集合不能对其插入或者删除文档。操作只能通过ensureIndex或者droplndexes进行。
查询索引明细
|
|
查询索引的大小
|
|
修改索引
MongoDB没有单独的修改索引方法,如果要修改某个索引,需要先删除旧的索引,再创建新的索引,
随着数据量的增长你会发现某个collection需要修改索引或者增加索引,此时创建索引就会很费力,同时也比较消耗性能。创建索引时MongoDB默认是阻塞式,会让索引建立更快,任何请求都不能相应。可以使用{ background:True } 选项再后台完成,同也可能正常处理请求。不过这种方式也会造成请求的响应很慢,如果再非紧急的情况下,最好晚上业务量少的时候统一处理。
地理空间索引
还有一种査询变得越来越流行(尤其是随着移动设备的出现):找到离当前位置最近的N个场所。MongoDB为坐标平面査询提供了专门的索引,称作地理空间索引。假设要找到给定经纬度坐标周围最近的咖啡馆,就需要创建一个专门的索引来提髙这种査询的效率,这是因为这种査询需要搜索两个维度。地理空间索引同样可以由ensurelndex来创建,只不过参数不是1或者-1,而是2d”:
|
|
“gps”键的值必须是某种形式的一对值:一个包含两个元素的数组或是包含两个键的内嵌文档。下面这些都是有效的:
|
|
至于键名可以随意,例如
|
|
也是可以的。
默认情况下,地理空间索引假设值的范围是-180 180 (对经纬度来说很方便)。要是想用其他值,可以通过ensurelndex的选项来指定最大最小值:
|
|
这样就创建了一个2000光年见方的空间索引。
地理空间査询以两种方式进行,即普通査询(用find)或者使用数据库命令。find的方式与一般的查询差别不大,只不过用了”$near”。需要两个目标值的数组作为参数:
|
|
这会按照离点(40, -73)由近及远的方式将map集合的所有文档都返回。在没有指定limit的值时,默认是100个文档。要是不需要这么多结果,就应该设置一个少点的值以节约资源。例如,下面的例子将返回离(40, -73)最近的10个文档。
|
|
也可以用geoNear来完成相同的操作:
|
|
geoNear还会返回每个文档到査询点的距离。这个距离是以你插入的数据为单位的,如果按照经纬度的角度插入,则距离就是经纬度。find与”$near”的组合不会给出距离,但若是结果大于4MB,这是唯一的选择
MongoDB不但能找到靠近一个点的文档,还能找到指定形状内的文档。做法就是将原来的n\$nearn换成”\$within”。n$within”获取数量不断增加的形状作为参数。若查看地理空间索引的联机帮助文档(http://www.mongodb.org/display/DOCS/Geospatial+ Indexing),可以找到最新的形状列表。有两个选项:你可以査询矩形和圆形内的所有点。
对于矩形,使用”$box”选项:
|
|
”$box”参数是两个元素的数组,第一个元素指定了左下角的坐标,第二个指定右上角的坐标。
同样,也可以用“”$center”来找到圆形内部的所有点,只不过参数变成了圆心和半径:
|
|
复合地理空间索引
应用经常要找的东西往往不只是一个地点。例如,用户要找出周围所有的咖啡店或者披萨店。将地理空间索引与普通索引组合起来就可以满足这种需求。例如,要査询”location”和”descn,就可以这样创建索引:
|
|
然后就能很快找到最近的咖啡馆了:
|
|
地球不是二维平面
MongoDB的地理空间索引假设索引内容是在一个平面上的。这就意味着对于球体,比如地球,它并不是十分精确,尤其是在极地区域。具体来说,两条经线之间纬线的长度在赤道和在育空地区1是大不一样的,后者要短得多。可以用不同的投影手段将地球映射到二维平面,当然它们的精度和相应的复杂度各不相同。
还没有评论,来说两句吧...