MongoDB 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()](https://www.mongodb.com/docs/manual/reference/method/db.collection.createIndex/#mongodb-method-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()](https://www.mongodb.com/docs/manual/reference/method/db.collection.getIndexes/#mongodb-method-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

https://www.mongodb.com/docs/manual/reference/method/db.collection.createIndex/#mongodb-method-db.collection.createIndex

Builds an index on a collection.

https://www.mongodb.com/docs/manual/reference/method/db.collection.dropIndex/#mongodb-method-db.collection.dropIndex

Removes a specified index on a collection.

https://www.mongodb.com/docs/manual/reference/method/db.collection.dropIndexes/#mongodb-method-db.collection.dropIndexes

Removes all indexes on a collection.

https://www.mongodb.com/docs/manual/reference/method/db.collection.getIndexes/#mongodb-method-db.collection.getIndexes

Returns an array of documents that describe the existing indexes on a collection.

https://www.mongodb.com/docs/manual/reference/method/db.collection.reIndex/#mongodb-method-db.collection.reIndex

Rebuilds all existing indexes on a collection.

https://www.mongodb.com/docs/manual/reference/method/db.collection.totalIndexSize/#mongodb-method-db.collection.totalIndexSize

Reports the total size used by the indexes on a collection. Provides a wrapper around the https://www.mongodb.com/docs/manual/reference/command/collStats/#mongodb-data-collStats.totalIndexSize field of the https://www.mongodb.com/docs/manual/reference/command/collStats/#mongodb-dbcommand-dbcmd.collStats output.

https://www.mongodb.com/docs/manual/reference/method/cursor.explain/#mongodb-method-cursor.explain

Reports on the query execution plan for a cursor.

https://www.mongodb.com/docs/manual/reference/method/cursor.hint/#mongodb-method-cursor.hint

Forces MongoDB to use a specific index for a query.

https://www.mongodb.com/docs/manual/reference/method/cursor.max/#mongodb-method-cursor.max

Specifies an exclusive upper index bound for a cursor. For use with https://www.mongodb.com/docs/manual/reference/method/cursor.hint/#mongodb-method-cursor.hint

https://www.mongodb.com/docs/manual/reference/method/cursor.min/#mongodb-method-cursor.min

Specifies an inclusive lower index bound for a cursor. For use with https://www.mongodb.com/docs/manual/reference/method/cursor.hint/#mongodb-method-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 indexes2dsphere indexes

详情见: Geospatial Indexes (mongodb.com)

文本索引(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索引会忽略索引键值的大小写。

参考

Indexes

最后更新于