索引
概述
在此指南中,您可以了解如何使用 Rust 驱动程序创建和管理 索引。索引是特殊的数据结构,可提高 MongoDB 中的查询性能。
如果您在没有任何索引的集合上执行查询,MongoDB 将扫描每个文档以找到匹配项。这些集合扫描很慢,可能会负面影响应用程序的性能。当您创建覆盖查询的索引时,MongoDB 将限制检查以找到匹配项的文档数,从而提高性能。
提示
您可以在更新操作、删除操作和某些聚合管道阶段中使用索引。有关在聚合中使用索引的更多信息,请参阅服务器手册中的使用索引和文档过滤器提高性能
查询覆盖率和性能
以下表格描述了您可以在 MongoDB 查询中包含的元素
元素 | 描述 |
---|---|
查询 | 必需 指定要匹配的字段和值 |
选项 | 可选 指定查询的执行方式 |
投影 | 可选 指定MongoDB在匹配的文档中返回的字段 |
排序 | 可选 指定返回文档的顺序 |
当你的查询元素引用的字段都包含在同一个索引中时,MongoDB可以直接从索引中返回结果。这些查询被称为覆盖查询。
要了解如何确保你的索引覆盖你的查询,请参阅服务器手册中的覆盖查询。
重要
排序条件
你的排序条件必须匹配或反转索引的顺序。
假设有一个集合在name
字段上有一个升序(A-Z)索引,在age
字段上有一个降序(9-0)索引
name_1_age_-1
MongoDB会使用这个索引,当你按以下配置排序文档时
name
升序,age
降序name
降序,age
升序
如果你为两个字段指定相同的排序顺序,MongoDB不会使用索引,而是执行内存排序。
操作注意事项
为了提高查询性能,在查询中经常出现的字段上创建索引。然而,跟踪索引的内存和磁盘使用情况对于容量规划来说是一个好习惯,因为每个索引都会消耗磁盘空间和内存。此外,如果写操作更新了索引字段,MongoDB还必须更新相关的索引。
MongoDB支持动态模式,因此你的应用程序可以查询未知或可变名称的字段。如果你连接到MongoDB服务器版本4.2或更高版本,你可以创建通配符索引来支持这些查询。有关此索引类型的更多信息,请参阅服务器手册中的通配符索引。
索引类型
MongoDB支持多种索引类型以支持您的查询。以下部分描述了常见的索引类型,并展示了如何在集合中创建每种索引类型。
您可以使用create_index()
和create_indexes()
方法在集合中创建索引。`create_index()`方法接受一个IndexModel
结构参数,您可以使用类型的builder()
方法来构建它。
要查看索引类型的完整列表,请参阅服务器手册中的索引类型。
单字段索引
单字段索引包含对文档字段的引用。
此索引提高了单字段查询和排序的性能。它还支持TTL索引,在指定时间后自动从集合中删除文档。有关TTL索引的更多信息,请参阅服务器手册中的TTL索引。
当您创建新的集合时,MongoDB会自动在_id
字段上创建一个唯一的单字段索引。
示例
以下代码在sample_training.zips
集合中city
字段上创建了一个升序索引
let index = IndexModel::builder().keys(doc! { "city": 1 }).build(); let idx = my_coll.create_index(index).await?; println!("Created index:\n{}", idx.index_name);
Created index: city_1
组合索引
组合索引包含多个文档字段的引用。
此索引可以提高多个字段上的查询和排序性能。创建组合索引时,必须为每个索引字段指定一个方向。
可以使用创建单个字段索引的相同语法来创建多键索引。
示例
以下代码在sample_training.zips
集合中city
和pop
字段上创建了一个组合索引
let index = IndexModel::builder() .keys(doc! { "city": 1, "pop": -1 }) .build(); let idx = my_coll.create_index(index).await?; println!("Created index:\n{}", idx.index_name);
Created index: city_1_pop_-1
多键索引(数组字段索引)
多键索引包含对数组值字段的引用。此索引可提高数组字段查询的性能。
可以使用创建单个字段索引的相同语法来创建多键索引。
示例
以下代码在sample_training.posts
集合的tags
字段上创建一个多键索引
let index = IndexModel::builder().keys(doc! { "tags": 1 }).build(); let idx = my_coll.create_index(index).await?; println!("Created index:\n{}", idx.index_name);
Created index: tags_1
聚集索引
聚集索引可以提高聚集集合的插入、更新和删除操作的性能。聚集集合按照聚集索引键值的顺序存储文档。要了解更多关于这些集合的信息,请参阅服务器手册中的聚集集合。
您只能在创建集合时创建聚集索引。要创建聚集集合,请执行以下步骤
创建一个
ClusteredIndex
实例。调用
create_collection()
方法。将
clustered_index()
方法链接到create_collection()
方法,并将您的ClusteredIndex
实例作为clustered_index()
方法的参数。
您必须设置ClusteredIndex
结构体的以下字段
key
字段,用于指定键模式。此字段的值必须是{ _id: 1 }
。unique
字段,用于指定索引的唯一性。此字段的值必须是true
。
要创建一个自动使用所需值的ClusteredIndex
实例,可以调用该类型的default()
方法。
示例
以下代码在sample_training
数据库中创建名为items
的新集合时,在_id
字段上创建具有默认配置的聚集索引
let db = client.database("sample_training"); let cl_idx = ClusteredIndex::default(); db.create_collection("items") .clustered_index(cl_idx) .await?;
文本索引
文本索引支持对字符串内容的文本搜索查询。此索引引用具有字符串值或字符串数组值的字段。MongoDB支持多种语言的文本搜索。在创建文本索引时,您可以指定默认语言作为选项。
集合只能包含一个文本索引。要创建多个文本字段的文本索引,可以创建复合索引。在创建复合索引后执行文本搜索时,搜索操作将在复合索引中的所有文本字段上运行。
示例
以下代码在sample_training.posts
集合中的body
字段上创建了一个文本索引。代码设置了一个选项,指定文本索引的默认语言为"spanish"
let idx_opts = IndexOptions::builder() .default_language("spanish".to_string()) .build(); let index = IndexModel::builder() .keys(doc! { "body": "text" }) .options(idx_opts) .build(); let idx = my_coll.create_index(index).await?; println!("Created index:\n{}", idx.index_name);
Created index: body_"text"
地理空间索引
MongoDB通过使用2dsphere
索引支持包含地理坐标数据的查询。您可以在具有GeoJSON对象值的字段上创建一个2dsphere
索引。
此索引类型支持以下任务
对地理空间数据进行包含、交集和邻近性查询
在欧几里得平面上计算距离
重要
您不能在同一个字段上创建两个地理空间索引。
示例
以下在sample_mflix.theaters
集合中的示例文档包含字段location.geo
。此字段具有GeoJSON点值
{ "_id": ..., "theaterId": ..., "location": { "address": ..., "geo": { "type": "Point", "coordinates": [ -93.24565, 44.85466 ] } } }
以下代码在sample_mflix.theaters
集合中的location.geo
字段上创建了一个地理空间2dsphere
索引
let index = IndexModel::builder() .keys(doc! { "location.geo": "2dsphere" }) .build(); let idx = my_coll.create_index(index).await?; println!("Created index:\n{}", idx.index_name);
Created index: location.geo_"2dsphere"
唯一索引
唯一索引确保索引字段不存储重复值。默认情况下,当您创建集合时,MongoDB会在_id
字段上创建一个唯一的单字段索引。
要创建唯一索引,指定您希望保持唯一性的字段或字段组合,并将unique
选项设置为true
。
示例
以下代码展示了如何在IndexOptions
实例中将unique
字段设置为true
,并在创建IndexModel
时传递这些选项
let opts = IndexOptions::builder().unique(true).build(); let index = IndexModel::builder() .keys(doc! { "_id": -1 }) .options(opts) .build();
删除索引
您可以从集合中删除任何索引,但不能删除在_id
字段上的默认唯一索引。要删除索引,将索引的名称传递给drop_index()
方法。
提示
删除所有索引
您可以使用drop_indexes()
方法一次性删除集合上的所有索引,除了_id
索引。
以下示例展示了如何从sample_training.zips
集合中删除名为city_1
的索引
my_coll.drop_index("city_1".to_string()).await?;
附加信息
要了解更多关于设计数据模型和为您的应用程序创建适当索引的信息,请参阅服务器手册中的索引策略和操作因素和数据模型。
要了解如何执行读取操作,请参阅读取操作类别中的指南。
要了解本指南中提到的概念,请参阅以下服务器文档
API文档
要了解本指南中提到的方法和类型,请参阅以下API文档