索引
在此页面上
Overview
在本指南中,您可以学习;了解如何通过MongoDB .NET/ C#驱动程序使用索引。 索引可以提高查询效率,并增加查询和存储文档的功能。
如果没有索引, MongoDB必须扫描集合中的每个文档,以查找与每个查询匹配的文档。 这些集合扫描很慢,可能会对应用程序的性能产生负面影响。 但是,如果查询存在适当的索引, MongoDB就可以使用该索引来限制必须检查的文档。
查询覆盖和性能
当您对MongoDB执行查询时,查询可以包含各种元素:
指定要查找的字段和值的查询条件
影响查询执行的选项,例如读关注
用于指定您希望MongoDB返回的字段的投影条件
排序条件,用于指定从MongoDB返回的文档的顺序
当查询、投影和排序中指定的所有字段都位于同一索引中时, MongoDB会直接从该索引返回结果,这也称为覆盖查询。
有关如何确保索引涵盖查询条件和投影的详细信息,请参阅MongoDB服务器手册中的涵盖的查询部分。
操作注意事项
若要提高查询性能,请对应用程序查询中经常出现的字段以及其他操作返回的排序结果中经常出现的字段建立索引。您添加的每个索引在活动状态下都会占用磁盘空间和内存,因此您可能需要跟踪索引内存和磁盘使用情况以进行容量规划。此外,当写入操作更新索引字段时,MongoDB 还会更新相关索引。
由于 MongoDB 支持动态模式,因此应用程序可以查询事先无法知道名称或具有任意名称的字段。MongoDB 4.2 引入了通配符索引,以帮助支持这些查询。通配符索引并不是为了取代基于工作负载的索引规划而设计的。
有关设计数据模型和选择适合应用程序的索引的更多信息,请参阅有关“索引策略”和“数据建模和索引”的服务器文档。
索引类型
MongoDB提供了几种不同的索引类型来支持数据查询。 以下部分描述了最常见的索引类型,并提供了创建每种索引类型的示例代码。
注意
这些示例使用Atlas示例数据集中的 sample_mflix.movies
和sample_mflix.theaters
集合。 要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅快速入门。
单字段索引
单字段索引是引用集合文档中单个字段的索引。 它们提高了单字段查询和排序性能,并支持TTL索引,该索引会在一定时间后或在特定时钟时间自动从集合删除文档。
注意
_id_
索引是单字段索引的一个示例。 创建新集合时,会在_id
字段上自动创建此索引。
以下示例对sample_mflix.movies
集合中的title
字段按升序创建索引:
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys.Ascending(m => m.Title)); collection.Indexes.CreateOne(indexModel);
以下是前面代码段中创建的索引涵盖的查询示例:
// Define query parameters var filter = Builders<Movie>.Filter.Eq(m => m.Title, "Batman"); var sort = Builders<Movie>.Sort.Ascending(m => m.Title); var projection = Builders<Movie>.Projection.Include(m => m.Title).Exclude(m => m.Id); // Execute query var results = collection.Find(filter).Sort(sort).Project(projection);
有关更多信息,请参阅服务器手册中的单字段索引。
复合索引
复合索引保存对集合文档中多个字段的引用,从而提高查询和排序性能。
以下示例在sample_mflix.movies
集合中的type
和rated
字段上创建复合索引:
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys .Ascending(m => m.Type) .Ascending(m => m.Rated)); collection.Indexes.CreateOne(indexModel);
以下是前面代码段中创建的索引涵盖的查询示例:
// Define query parameters var typeFilter = Builders<Movie>.Filter.Eq(m => m.Type, "movie"); var ratedFilter = Builders<Movie>.Filter.Eq(m => m.Rated, "G"); var filter = Builders<Movie>.Filter.And(typeFilter, ratedFilter); var sort = Builders<Movie>.Sort.Ascending(m => m.Type).Ascending(m => m.Rated); var projection = Builders<Movie>.Projection .Include(m => m.Type) .Include(m => m.Rated) .Exclude(m => m.Id); // Execute query var results = collection.Find(filter).Sort(sort).Project(projection);
有关详细信息,请参阅服务器手册中的复合索引。
Multikey Indexes
多键索引从包含大量值的字段中收集数据并进行排序。 您可以使用与单字段或复合索引。
以下示例在sample_mflix.movies
集合中的rated
、 genres
(字符串大量)和title
字段上创建复合多键索引:
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys .Ascending(m => m.Rated) .Ascending(m => m.Genres) .Ascending(m => m.Title)); collection.Indexes.CreateOne(indexModel);
以下是前面代码段中创建的索引涵盖的查询示例:
// Define query parameters var genreFilter = Builders<Movie>.Filter.AnyEq(m => m.Genres, "Animation"); var ratedFilter = Builders<Movie>.Filter.Eq(m => m.Rated, "G"); var filter = Builders<Movie>.Filter.And(genreFilter, ratedFilter); var sort = Builders<Movie>.Sort.Ascending(m => m.Title); var projection = Builders<Movie>.Projection .Include(m => m.Title) .Include(m => m.Rated) .Exclude(m => m.Id); // Execute query var results = collection.Find(filter).Sort(sort).Project(projection);
多键索引在查询覆盖、索引绑定计算和排序行为方面的行为与其他索引不同。 要学习;了解有关多键索引的更多信息,包括对其行为和限制的讨论,请参阅服务器手册中的多键索引页面。
聚集索引
集群化索引指示集合存储按键值排序的文档。 要创建聚集索引,请在创建集合时指定聚集索引选项,并将_id
字段指定为键,并将Unique
属性指定为true
。 一个集合只能包含一个集群索引。 如果要创建聚集索引,则必须在创建集合时指定。
以下示例在创建新的sample_mflix.reviews
集合时对_id
字段创建集群索引:
var database = mongoClient.GetDatabase("sample_mflix"); var clusteredIndexOptions = new ClusteredIndexOptions<Review> { Key = Builders<Review>.IndexKeys.Ascending(r => r.Id), Unique = true }; database.CreateCollection("reviews", new CreateCollectionOptions<Review> { ClusteredIndex = clusteredIndexOptions });
Atlas Search 索引
Atlas Search 功能使您能够对 MongoDB Atlas 上托管的集合执行全文搜索。索引指定了搜索行为以及要索引的字段。
如需了解有关 MongoDB Atlas Search 的更多信息,请参阅“Atlas Search 索引”文档。
注意
Atlas Search索引管理方法异步运行。 驾驶员方法可以在确认成功运行之前返回。 要确定索引的当前状态,请调用 IMongoSearchIndexManager.List() 方法。
以下部分包含演示如何创建Atlas Search索引并交互的教程链接。
创建搜索索引
在对Atlas集合执行搜索之前,必须先在该集合上创建Atlas Search索引。 要学习;了解如何使用.NET/ C#驱动程序创建Atlas Search索引,索引参阅Atlas手册中的创建 Atlas Search 索引,然后从语言下拉列表中选择 C# 。
搜索索引列表
要学习;了解如何使用.NET/ C#驱动程序查看 Atlas Atlas Search索引列表,请参阅Atlas手册中的“Atlas Search索引”,然后从语言下拉列表中选择C# 。
更新搜索索引
要学习;了解如何使用.NET/ C#驱动程序修改现有Atlas Search索引,请参阅Atlas手册中的编辑Atlas Search索引,然后从语言下拉列表中选择C# 。
删除搜索索引
要学习;了解如何使用.NET/ C#驱动程序删除Atlas Atlas Search索引,请参阅Atlas手册中的Atlas Search索引,然后从语言下拉列表中选择C# 。
Text Indexes
文本索引支持对字符串内容进行文本搜索查询。这些索引可以包括任何值为字符串或字符串元素数组的字段。MongoDB 还支持各种语言的文本搜索。在创建索引时,可以指定默认语言作为选项。
提示
MongoDB 提供改进的全文搜索解决方案 Atlas Search。如需了解有关 Atlas Search 索引以及使用方法的更多信息,请参阅本指南的“Atlas Search 索引”部分。
请注意,文本索引不支持Atlas Search查询, Atlas Search索引也不支持文本查询。
单个字段
以下示例在sample_mflix.movies
集合内的plot
字段上创建文本索引:
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys.Text(m => m.Plot)); collection.Indexes.CreateOne(indexModel);
以下查询使用前面代码片段中创建的文本索引:
// Define query parameters var filter = Builders<Movie>.Filter.Text("java coffee shop"); var projection = Builders<Movie>.Projection.Include(m => m.Plot).Exclude(m => m.Id); // Execute query var results = collection.Find(filter).Project(projection);
多个字段
一个集合只能包含一个文本索引。如果要为多个文本字段创建文本索引,必须创建复合索引。文本搜索在复合索引内的所有文本字段上运行。
以下代码片段为sample_mflix.movies
集合中的title
和genre
字段创建复合文本索引:
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys .Text(m => m.Title) .Text(m => m.Genre)); collection.Indexes.CreateOne(indexModel);
地理空间索引
MongoDB支持使用2 dsphere 索引查询地理空间坐标数据。 通过2 dsphere索引,您可以查询地理空间数据以了解包含、相交和邻近范围。
要创建2 dsphere索引,您必须指定仅包含GeoJSON对象的字段。 有关此类型的更多详细信息,请参阅MongoDB Server手册中的GeoJSON对象。
以下示例文档中sample_mflix.theaters
集合中的location.geo
字段是一个GeoJSON点对象,用于描述影院的坐标:
{ "_id" : ObjectId("59a47286cfa9a3a73e51e75c"), "theaterId" : 104, "location" : { "address" : { "street1" : "5000 W 147th St", "city" : "Hawthorne", "state" : "CA", "zipcode" : "90250" }, "geo" : { "type" : "Point", "coordinates" : [ -118.36559, 33.897167 ] } } }
以下示例在 location.geo
字段上创建一个 2dsphere
索引:
重要
尝试在已被地理空间索引覆盖的字段上创建地理空间索引会导致错误。
var indexModel = new CreateIndexModel<Theater>(Builders<Theater>.IndexKeys.Geo2DSphere(t => t.Location.Geo)); collection.Indexes.CreateOne(indexModel);
以下是使用“ 位置 ”的地理空间查询示例 索引:
// Stores the coordinates of the NY MongoDB headquarters var refPoint = GeoJson.Point(GeoJson.Position(-73.98456, 40.7612)); // Creates a filter to match documents that represent locations up to 1000 meters from the specified point directly from the geospatial index var filter = Builders<Theater>.Filter.Near(m => m.Location.Geo, refPoint, 1000.0, 0.0); // Execute the query var results = collection.Find(filter);
MongoDB还支持2d
索引,用于计算欧几里得平面上的距离,以及使用legacy coordinate pairs MongoDB2.2及更早版本中使用的“ ”语法。要了解更多信息,请参阅 MongoDB Server手册中的 地理空间查询 。
Unique Indexes
唯一索引可确保索引字段不存储重复值。 默认, MongoDB在创建集合期间在_id
字段上创建唯一索引。 要创建唯一索引,请指定要防止重复的字段,设立Unique
选项设置为true
。
以下示例在sample_mflix.theaters
集合中的theaterId
字段上创建唯一的降序索引。
var options = new CreateIndexOptions { Unique = true }; var indexModel = new CreateIndexModel<Theater>(Builders<Theater>.IndexKeys.Descending(t => t.TheaterId), options); collection.Indexes.CreateOne(indexModel);
如果您的写操作违反了唯一索引的规则,即尝试对索引字段存储重复的值, MongoDB 将抛出类似以下的报错:
E11000 duplicate key error index
要学习;了解更多信息,请参阅服务器手册中的唯一索引。
通配符索引 (Wildcard Indexes)
通配符索引启用对未知或任意字段进行查询。 如果使用动态模式,这些索引可能很有用。
以下示例对sample_mflix.theaters
集合中location
字段的所有值(包括嵌套在子文档和数组中的值)创建升序通配符索引:
var indexModel = new CreateIndexModel<Theater>(Builders<Theater>.IndexKeys.Wildcard(t => t.Location)); collection.Indexes.CreateOne(indexModel);
有关详细信息,请参阅服务器手册中的通配符索引页面。
列出索引
您可以使用 List() 方法以检索集合中的索引列表。
以下示例使用List()
方法列出集合中的所有索引:
var indexes = collection.Indexes.List(); foreach (var index in indexes.ToList()) { Console.WriteLine(index); }