索引的概述

什么是索引

索引支持在MongoDB中高效的执行,没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每一个文档,已选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟。

如果查询存在适当的索引,MongoDB可以使用改索引限制必须检查的文档数。
索引是特殊的数据结构,它以一种易于遍历的形式存储集合数据集的一小部分。索引存储一个或一组特定字段的值,按字段的值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB可以通过使用索引中的排序返回排序后的结果。

索引的类型

单字段索引

MongoDB支持在文档的单个字段上创建用户定义的升序降序索引称为单字段索引。

对于单个字段索引和排序操作,索引健的排序顺序并不重要,因为MongoDB可以在任何方向上遍历索引。

单键索引(Single Field Indexes)顾名思义就是单个字段作为索引列,mongoDB的所有collection默认都有一个单键索引_id,我们也可以对一些经常作为过滤条件的字段设置索引

复合索引

MingoDB还支持多个字段的用户定义索引,即复合索引

复合索引中列出的字段顺序具有重要意义。例如,如果复合索引由{userid:1,score:-1}组成,则索引首先按userid正序排序,然后在每一个userid的值内,再按score倒序排序

复合索引(Compound Indexes)指一个索引包含多个字段,用法和单键索引基本一致。使用复合索引时要注意字段的顺序,如下添加一个name和age的复合索引,name正序,age倒序,document首先按照name正序排序,然后name相同的document按age进行倒序排序。mongoDB中一个复合索引最多可以包含32个字段。

其他索引

地理空间索引(Geospatial index)、文本索引(TextIndexes)、哈希索引(Hashed indexes)

地理空间索引(Geospatial index)

为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引,返回结果时使用平面几何的二维索引和返回结果时使用平面几何的二维索引和返回结果时使用球面几何的二维球面索引

文本索引(TextIndexes)

MongoDB提供了一种文本索引类型,支持在集合搜索字符串内容,这些文本索引不存储特定于语言的停止词而将集合中的词作为词干,只存储根词。

哈希索引(Hashed indexes)

为了支持基于散列的分片,MongoDB提供了散列索引类型,它对字段值的散列进行索引。这些索引在其范围内的值分布更加随机,但1只支持相等匹配,不支持基于范围的查询。

索引的管理操作

索引的查看

 说明:

返回一个集合中的所有索引的数组

语法:

db.collection.getIndexes()

索引的创建

说明:

在集合上创建索引

语法:

db.collection.createIndex(keys,options)

参数:

参数

类型

描述

keys

文献

包含字段和值对的文档,其中字段是索引键,而值描述该字段的索引类型。对于字段上的升序索引,将值指定为1;对于降序索引,将值指定为-1。从3.6开始,您不能指定*作为索引名称。

MongoDB支持几种不同的索引类型,包括 textgeospatialhashed索引。有关 更多信息,请参见索引类型


在版本4.2中进行了更改: MongoDB 4.2 通配符索引 支持工作负载,用户可以在其中查询自定义字段或集合中多种字段:

  • 要在文档的所有字段和子字段上创建通配符索引,请指定作为索引键。创建通配符索引时,不能指定降序索引键。{ "$**" : 1 }您还可以使用可选参数从索引中包含排除特定字段及其子字段 wildcardProjection
    _id默认情况下,通配符索引会忽略该字段。要将_id字段包括 在通配符索引中,必须在wildcardProjection文档中明确包含它:
{
  "wildcardProjection" : {
    "_id" : 1,
    "<field>" : 0|1
  }
}

除了显式包含 _id字段外,您无法在wildcardProjection文档中组合包含和排除语句 。

  • 您可以在特定字段及其子路径上创建通配符索引,方法是将该字段的完整路径指定为索引键并附"$**"加到该路径:
    { "path.to.field.$**" : 1 }创建通配符索引时,不能指定降序索引键。
    特定于路径的通配符索引语法与该wildcardProjection选项不兼容 。您不能在指定的路径上指定其他包含或排除。

通配符索引键必须使用上面列出的语法之一。例如,您不能指定 复合索引键。有关通配符索引的更完整文档(包括对其创建的限制),请参见通配符索引限制

featureCompatibilityVersion必须创建通配符索引。有关设置fCV的说明,请参阅 在MongoDB 4.2部署上设置功能兼容版本mongod 4.2


有关创建通配符索引的示例,请参见 创建通配符索引

options

文献

可选的。包含一组控制索引创建的选项的文档。有关详细信息,请参见选项

db.collection.createIndex()是围绕着一个包装 createIndexes命令。

为了最大程度地减少在副本集和分片群集上建立索引的影响,请使用滚动索引生成过程,如在副本集建立索引所述。

选项

options文档包含一组控制索引创建的选项。不同的索引类型可以具有特定于该类型的其他选项。

在版本3.4中进行了更改:添加了对归类选项的支持。

对于所有索引类型选项

除非另有说明,否则以下选项可用于所有索引类型:

参数

类型

描述

background

布尔值

可选的。在MongoDB 4.2中已弃用。

  • 对于功能兼容版本(fcv) "4.0",指定可指示MongoDB在后台构建索引。后台构建 不会阻止对集合的操作。默认值为 。background: truefalse
  • 在版本4.2中进行了更改。
    对于功能兼容版本(fcv) "4.2",所有索引构建都使用优化的 构建过程,该过程仅在构建过程的开始和结束时才保留排他锁。其余的构建过程将产生交错的读写操作。background如果指定,MongoDB将忽略该选项。

unique

布尔值

可选的。创建唯一索引,以便在索引键值与索引中现有值匹配的集合中,该集合将不接受文档的插入或更新。

指定true以创建唯一索引。默认值为false

该选项不适用于哈希 索引。

name


可选的。索引名称。如果未指定,则MongoDB通过串联索引字段的名称和排序顺序来生成索引名称。


在MongoDB 4.2中已更改

从4.2版开始,对于featureCompatibilityVersion设置为"4.2"或更大的版本,MongoDB删除了 最大127个字节的限制。在featureCompatibilityVersionfCV)设置为以前的版本或MongoDB版本 中 ,索引名称必须在内 。Index Name Length"4.0"limit


partialFilterExpression

文献

可选的。如果指定,则索引仅引用与过滤器表达式匹配的文档。有关更多信息,请参见部分索引

过滤器表达式可以包括:

您可以partialFilterExpression为所有MongoDB 索引类型指定一个选项 。


3.2版中的新功能。


sparse

布尔值

可选的。如果为true,则索引仅引用具有指定字段的文档。这些索引使用较少的空间,但是在某些情况下(尤其是排序)表现不同。默认值为false。有关更多信息,请参见稀疏索引

默认情况下,以下索引类型是稀疏的,并且忽略此选项:

对于包含2dsphere索引键和其他类型的键的复合索引,只有2dsphere索引字段才能确定索引是否引用文档。


在版本3.2中进行了更改:从MongoDB 3.2开始,MongoDB提供了创建部分索引的选项 。部分索引提供了稀疏索引功能的超集。如果您使用的是MongoDB 3.2或更高版本,则应优先使用部分索引而不是稀疏索引。


expireAfterSeconds

整数

可选的。指定一个值(以秒为单位)作为TTL,以控制MongoDB在此集合中保留文档的时间。有关此功能的更多信息,请参见 通过设置TTL从集合中过期数据。这仅适用于TTL索引。

storageEngine

文献

可选的。允许用户在创建索引时基于每个索引配置存储引擎。

storageEngine选项应采用以下形式:




storageEngine: { <storage-engine-name>: <options> }




创建索引时进行验证,并记录到指定的存储引擎的配置选项OPLOG复制到支持副本集与使用不同的存储引擎成员中。

整理选项

3.4版的新功能。

警告

MongoDB 3.2和更早版本不支持排序规则。在MongoDB 3.2和更早版本中,请勿使用不受支持的排序规则选项创建索引,因为这将阻止升级到3.4,这将强制对索引选项进行更严格的验证

参数

类型

描述

collation

文献

可选的。指定索引的排序规则

归类允许用户为字符串比较指定特定于语言的规则,例如字母大写和重音符号的规则。

如果您在集合级别指定了排序规则,则:

  • 如果在创建索引时未指定排序规则,则MongoDB将使用集合的默认排序规则创建索引。
  • 如果在创建索引时确实指定了排序规则,则MongoDB会使用指定的排序规则创建索引。

排序规则选项具有以下语法:




collation: {
   locale: <string>,
   caseLevel: <boolean>,
   caseFirst: <string>,
   strength: <int>,
   numericOrdering: <boolean>,
   alternate: <string>,
   maxVariable: <string>,
   backwards: <boolean>
}




指定排序规则时,该locale字段为必填字段;所有其他排序规则字段都是可选的。有关字段的说明,请参见整理文档


3.4版的新功能。


以下索引仅支持简单的二进制比较,不支持排序规则

示例(单字段索引的添加 1什序 -1降序)

db.test.createIndex({userid:1})

复合索引的示例

db.test.createIndex({age:1,nickname:-1})

索引的移除

说明:可以移除指定的索引,或移除所有索引

一、指定索引的移除

db.collection.dropIndex(index)

参数

db.collection.dropIndexes()方法采用以下可选参数:

参数

类型

描述

indexes

字符串或文档或字符串数组

可选的。指定要删除的一个或多个索引。

要删除集合中除_id索引以外的所有索引,请省略参数。

要删除单个索引,请指定索引名称,索引规范文档(除非索引是 文本索引)或索引名称的数组。要删除文本索引,请指定索引名称或索引名称的数组,而不是索引规范文档。

要删除多个索引(从MongoDB 4.2开始可用),请指定一个索引名称数组。

db.collection.dropIndexes()是围绕着一个包装 dropIndexes命令。

示例

db.test.dropIndex({userid:1});
提示_id的字段的索引是无法删除的,只能删除非_id字段的索引。

 索引的使用

执行计划

分析查询性能通常使用查询计划来查看查询的详情,如:查询耗费的时间、是否基于索引查询等。

那么、通常、我们想知道、建立的索引是否有效、效果如何、都需要执行计划查看。

语法:

db.collection.find(query,options).explain(options)

示例

db.test.find({userid:"1003"}).explain()

涵盖的查询

Covered Queies

当查询条件和查询的投影包含索引的字段时候,MongoDB直接从索引返回结果,而不扫描成文档或将文档带入内存。这些覆盖的查询可以非常有效。

db.collection.find({userid:"1003"},{userid:1,_id:0})
或者
db.collection.find({userid:"1003"},{userid:1,_id:0}).expain()