MongoDB-Indexes索引
indexes索引索引管理创建索引语法索引名称获取索引删除索引索引API参考索引类型单字段索引(Single Field Indexes)复合索引(Compound Indexes)匹配全部或者一部分字段创建复合索引顺序多键索引(MultiKey Indexes)创建多键索引地理空间索引(Geospatial Indexes)文本索引(Text Indexes)创建文本索引通配符支持复合索引哈希索引(Hashed Indexes)创建哈希索引集群索引(Clustered Indexes)索引属性唯一索引(Unique Indexes)部分索引(Partial Indexes)稀疏索引TTL IndexesHidden IndexesCase Insensitive Indexes参考
indexes索引
索引能让MongoDB查询变得更加高效,如果没有索引,MongoDB就需要扫描集合中的所有文档,然后再将每个文档进行匹配,选出匹配成功的文档。如果在查询中能够适当地使用索引,那么MongoDB就可以利用该索引去限制查询文档的个数,从而提交查询效率。
索引以一种特殊的数据格式存储,它以一种易于遍历的形式存储了集合数据集的一小部分。索引存储着一个特定字段的值或者一些系列字段的值,并按照字段的值排序。索引项的排序支持高效的相等匹配和基于范围的查询操作。此外,MongoDB可以通过使用索引中的排序来返回排序的结果。
如上图所示,索引将
score
按升序排序,当使用范围查询时可以很高效地匹配结果并按照规定顺序返回。需要注意的是,虽然索引可以使查询更加高效,但是索引本身会存储一定的空间,因此索引并不是越多越好,应当适当地使用索引。
MongoDB默认为_id创建索引,并添加唯一性约束(unique)。
索引管理
创建索引
语法
shell中通过createIndex来创建索引。
语法:
db.collection.createIndex( <key and index type specification>, <options> )
示例:
db.collection.createIndex( { name: -1 } )
这条语句创建了一个
name
字段的索引,并按照降序排序。name
表示为文档字段name
创建索引,-1
表示按降序排序,除此之外也可以传入1
,表示升序排序。db.collection.createIndex()
只能创建索引,如果之前存在相同规则的索引,则该语句将不起作用。索引名称
如果没有显示指明索引名,MongoDB会自动生成索引名,
格式:
${name}_${value}
例如上面的
db.collection.createIndex( { name: -1 } )
,创建的索引名就是name_-1
一旦索引被创建,就不能再重命名。
创建索引时显示指定索引名称的语法示例如下:
db.products.createIndex( { item: 1, quantity: -1 } , { name: "query for inventory" } )
获取索引
可以通过
db.collection.getIndexes()
来获取集合中的索引。但是需要注意,一旦索引被创建,就不能重命名,删除索引
db.collection.dropIndex() // Removes a specified index on a collection. db.collection.dropIndexes() // Removes all indexes on a collection.
索引API参考
Name | Description |
Builds an index on a collection. | |
Removes a specified index on a collection. | |
Removes all indexes on a collection. | |
Returns an array of documents that describe the existing indexes on a collection. | |
Rebuilds all existing indexes on a collection. | |
Reports the total size used by the indexes on a collection. Provides a wrapper around the totalIndexSize field of the collStats output. | |
Reports on the query execution plan for a cursor. | |
Forces MongoDB to use a specific index for a query. | |
Specifies an exclusive upper index bound for a cursor. For use with cursor.hint() | |
Specifies an inclusive lower index bound for a cursor. For use with cursor.hint() |
索引类型
MongoDB提供了许多不同的索引类型来支持特定类型的数据和查询。
单字段索引(Single Field Indexes)
对于单字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任意方向遍历索引。
单字段索引是最简单的索引,它能提高等值查询和范围查询的效率。
db.records.createIndex( { score: 1 } ) // 建立单字段索引 db.records.find( { score: 2 } ) // 等值查询 db.records.find( { score: { $gt: 10 } } ) // 范围查询
如果是嵌套文档,则可以通过
.
来选中嵌套文档的字段。{ "_id": ObjectId("570c04a4ad233577f97dc459"), "score": 1034, "location": { state: "NY", city: "New York" } } db.records.createIndex( { "location.state": 1 } )
另一种情况是为嵌套文档整体建立索引,这在查询整个嵌套文档时非常有效。
{ "_id": ObjectId("570c04a4ad233577f97dc459"), "score": 1034, "location": { state: "NY", city: "New York" } } db.records.createIndex( { location: 1 } ) // 查询嵌套文档 db.records.find( { location: { city: "New York", state: "NY" } } )
注意这里是
复合索引(Compound Indexes)
MongoDB支持复合索引。假设这样的一个文档结构:
{ userid: 'aa1', score: 45 }
为其建立符合索引后,索引存储结构如下图所示:
需要注意地是,MongoDB限制每个复合索引最多包含32个字段。
匹配全部或者一部分字段
复合索引既可以用于所有字段的匹配,也可以用于单个字段的匹配:
db.products.find( { userid: "aa1" } ) db.products.find( { userid: "ca2", score: { $gt: 5 } } )
创建复合索引
创建复合索引的语法和创建单字段索引非常类似:
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )
示例:
db.collection.createIndex({userid: 1, score: -1})
顺序
在单字段索引中,顺序并不是那么的重要,因为MongoDB可以在任何方向上遍历索引,但是在复合索引中,字段顺序是非常重要的,它会影响索引的性能。
db.events.createIndex( { "username" : 1, "date" : -1 } ) // 支持 db.events.find().sort( { username: 1, date: -1 } ) db.events.find().sort( { username: -1, date: 1 } ) // 不支持 db.events.find().sort( { username: 1, date: 1 } )
多键索引(MultiKey Indexes)
如果为数组类型的字段建立索引,那么MongoDB就会为数组中每个元素创建索引键,这就是多键索引。多键索引支持高效地查询数组字段。
创建多键索引
创建多键索引和创建单字段索引的方式相同,只不过创建多键索引时,字段是一个数组。
如果在创建索引时,字段是一个数组,那么MongoDB将会自动为其创建多键索引,无需用户去明确地指定多键类型。
db.collection.createIndex( { <field>: < 1 or -1 > } )
地理空间索引(Geospatial Indexes)
MongoDB支持建立地理空间数据,MongoDB为其提供两种特别的索引:2d indexes 和 2dsphere indexes
文本索引(Text Indexes)
MongoDB提供文本索引来更高效地实现文本查询。文本索引可以用于任何值为字符串或字符串数组的字段。
一个集合中只能由一个文本搜索索引,但是这个文本搜索索引可以覆盖多个字段。
创建文本索引
创建文本索引的语法和创建复合类型非常相似,但是value是一个字符串。
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )
示例:
db.reviews.createIndex( { comments: "text" } ) // 多个字段 db.reviews.createIndex( { subject: "text", comments: "text" } )
当文本索引包含多个字段时,根据复合索引的特点我们知道,此时文本索引既可以支持其中某一个字段的查询,也可以支持所有字段的联合查询。
通配符
当在多个字段上创建文本索引时,你也可以使用通配符指定器
($**)
。使用通配符文本索引,MongoDB会对集合中每个文档中包含字符串数据的每个字段进行索引。下面的例子使用通配符指定器创建了一个文本索引:db.collection.createIndex( { "$**": "text" } )
支持复合索引
文本索引支持在创建时使用复合索引,即在创建索引时同时文本索引和其他索引。
哈希索引(Hashed Indexes)
哈希索引使用一个哈希函数来计算索引字段的值的哈希。哈希函数对嵌入文档进行折叠并计算整个值的哈希值,但不支持多键(即数组)索引。具体来说,在包含数组的字段上创建哈希索引,或者试图将数组插入哈希索引字段中,都会返回错误。
当使用哈希索引时,MongoDB会自动计算哈希值,不需要手动处理。
创建哈希索引
创建哈希索引时只需要将索引键的值设为
hashed
即可 。db.collection.createIndex( { _id: "hashed" } )
集群索引(Clustered Indexes)
从MongoDB 5.3开始,您可以创建一个具有聚集索引的集合。使用聚集索引创建的集合称为聚集集合。
索引属性
唯一索引(Unique Indexes)
唯一索引可以确保索引字段唯一性,避免产生重复。
部分索引(Partial Indexes)
部分索引只对符合指定筛选条件的文档进行索引。
稀疏索引
稀疏索引不会对没有索引字段的文档进行索引。
TTL Indexes
TTL索引是特殊的索引,MongoDB可以用来在一定时间后自动从一个集合中删除文档。这对于某些类型的信息来说是非常理想的,比如机器生成的事件数据、日志和会话信息,它们只需要在有限的时间内持续存在于数据库。
Hidden Indexes
隐藏索引对查询计划程序不可见。
Case Insensitive Indexes
Case Insensitive索引会忽略索引键值的大小写。