索引支持在MongoDB中有效地执行查询。如果没有索引,MongoDB必须执行集合扫描,即扫描集合中的每个文档,以选择那些与查询语句匹配的文档。如果一个查询存在适当的索引,MongoDB可以使用该索引来限制它必须检查的文档数量。
索引是特殊的数据结构,它以一种易于遍历的形式存储集合数据集的一小部分。索引存储一个或一组特定字段的值,按字段的值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB可以通过使用索引中的排序返回排序后的结果。
下图说明了使用索引选择和排序匹配文档的查询:
从根本上讲,MongoDB中的索引类似于其他数据库系统中的索引。MongoDB在集合 级别定义索引,并支持MongoDB集合中文档的任何字段或子字段的索引。
MongoDB 使用的是
B Tree
, MySQL 使用的是B+ Tree
默认id索引
在创建集合期间,MongoDB 在_id字段上创建唯一索引。该索引可防止客户端插入两个具有相同值的文档。你不能将_id
字段上的index删除。
[success] 注意 在分片群集中,如果您不使用_id字段作为分片键,那么您的应用程序 必须确保_id字段中值的唯一性以防止错误。这通常是通过使用标准的自动生成的ObjectId来完成的。
创建索引
要在Mongo Shell中创建索引 ,请使用 db.collection.createIndex().
db.collection.createIndex( <key and index type specification>, <options> )
以下示例在name字段上创建单个键降序索引:
db.collection.createIndex( { name: -1 } )
db.collection.createIndex方法只在不存在相同规范的索引时创建索引。
删除索引
// retrieve indexes
db.<collection_name>.getIndexes()
// remove indexes
db.<collection_name>.dropIndex(index)
// there are 2 ways to remove indexes:
// 1. removed based on the index name
// 2. removed based on the fields
db.<collection_name>.dropIndex( "userid_1_username_-1" )
db.<collection_name>.dropIndex({ userid : 1, username : -1 })
// remove all the indexes, will only remove non_id indexes
db.<collection_name>.dropIndexes()
索引名称
索引的默认名称是索引键和索引中每个键的方向(即1或-1)的连接,使用下划线作为分隔符。例如,在{ item : 1, quantity: -1 }上创建的索引名称为item1_quantity-1。
您可以创建具有自定义名称的索引,比如比默认名称更易于阅读的索引。例如,考虑一个经常查询products集合以填充现有库存数据的应用程序。下面的createIndex() 方法在名为查询的商品和数量上创建一个索引:
db.products.createIndex(
{ item: 1, quantity: -1 } ,
{ name: "query for inventory" }
)
可以使用db.collection.getIndexes() 方法查看索引名称。一旦创建索引,您将无法重命名。相反,您必须删除并使用新名称重新创建索引。
索引类型
单个字段
除MongoDB定义的_id索引外,MongoDB还支持在文档的单个字段上创建用户定义的升序/降序索引。
对于单字段索引和排序操作,索引键的排序顺序(升序或降序)并不重要,因为MongoDB可以从任何方向遍历索引。
有关单字段索引的更多信息,请参见单字段索引和使用单字段索引排序。
复合索引
MongoDB还支持多个字段上的用户定义索引,即 复合索引。
复合索引中列出的字段的顺序具有重要意义。例如,如果一个复合索引由{userid: 1, score: -1}
组成,索引首先按userid
排序,然后在每个userid
值内按score
排序。
对于复合索引和排序操作,索引键的排序顺序(即升序或降序)可以确定索引是否可以支持排序操作。有关索引顺序对复合索引结果的影响的更多信息,请参见 排序顺序。
有关复合索引的更多信息,请参见复合索引和在多个字段上排序。
多键索引
MongoDB使用多键索引来索引存储在数组中的内容。如果您对保存数组值的字段建立索引,则MongoDB将为数组的每个元素创建单独的索引条目。这些多键索引允许查询通过匹配数组的一个或多个元素来选择包含数组的文档。如果索引字段包含数组值,MongoDB会自动确定是否创建多键索引。您无需显式指定多键类型。
见多键索引和多键索引界 对多键索引的详细信息。
地理空间索引
为了支持对地理空间坐标数据的高效查询,MongoDB提供了两个特殊的索引:返回结果时使用平面几何的2d索引和使用球面几何返回结果的2dsphere索引。
有关地理空间索引的高级介绍,请参见2d Index Internals。
文本索引
MongoDB提供了一种text索引类型,该类型支持在集合中搜索字符串内容。这些文本索引不存储特定于语言的停用词(例如“ the”,“ a”,“ or”),并且在集合中词干仅存储根词。
有关文本索引和搜索的更多信息,请参见文本索引。
哈希索引
为了支持基于散列的分片,MongoDB提供了一种散列索引类型,该索引类型对字段值的散列进行索引。这些索引在其范围内具有更随机的值分布,但仅 支持相等匹配,而不能支持基于范围的查询。
索引属性
唯一索引¶
索引的unique属性使MongoDB拒绝索引字段的重复值。除了唯一约束之外,唯一索引在功能上可以与其他MongoDB索引互换。
部分索引¶
3.2版中的新功能。
部分索引仅索引集合中符合指定过滤器表达式的文档。通过索引集合中文档的子集,部分索引具有较低的存储需求,并降低了索引创建和维护的性能成本。
部分索引提供了稀疏索引功能的超集,应优先于稀疏索引。
稀疏索引¶
索引的稀疏属性可确保索引仅包含具有索引字段的文档的条目。索引会跳过没有索引字段的文档。
您可以将稀疏索引选项与唯一索引选项结合使用,以防止插入索引字段具有重复值的文档,并跳过缺少索引字段的索引文档。
TTL指数¶
TTL索引是MongoDB可以使用的特殊索引,可以在一定时间后自动从集合中删除文档。对于某些类型的信息(例如机器生成的事件数据,日志和会话信息),它们仅需要在数据库中保留有限的时间,这是理想的选择。
请参阅:通过设置TTL使集合中的数据过期以获取实现说明。
索引和排序规则
3.4版的新功能。
归类允许用户为字符串比较指定特定于语言的规则,例如字母大写和重音符号的规则。
https://docs.mongoing.com/indexes#suo-yin-he-pai-xu
覆盖查询
当查询标准和投影的查询包括 仅索引字段,MongoDB的直接从索引返回结果没有扫描的任何文件或文件带来到内存中。这些涵盖的查询可能非常有效。
有关覆盖查询的更多信息,请参见 覆盖查询。
索引交集
MongoDB可以使用索引的交集来完成查询。对于指定复合查询条件的查询,如果一个索引可以满足查询条件的一部分,而另一个索引可以满足查询条件的另一部分,则MongoDB可以使用两个索引的交集来满足查询。使用复合索引还是使用索引交集是否更有效取决于特定查询和系统。
有关索引交集的详细信息,请参见索引交集。
限制条件
某些限制适用于索引,例如索引键的长度或每个集合的索引数。有关详细信息,请参见索引限制。
其他注意事项
尽管索引可以提高查询性能,但是索引还提出了一些操作上的考虑。有关更多信息,请参见索引的操作注意事项。
应用程序在建立索引期间可能会遇到性能下降的情况,包括对集合的有限读/写访问权限。有关索引构建过程的更多信息,请参见“现存集合的索引构建”,包括“在复制集环境下的索引构建”章节
一些驱动程序可能指定索引,使用NumberLong(1)而不是1作为规范。这对结果索引没有任何影响。