Overview
在本指南中,您可以学习如何在 MongoDB Go 驱动程序中使用索引。
MongoDB 中的索引支持高效执行查询。如果没有索引,MongoDB 会扫描集合中的每个文档(集合扫描),从而找到与您的查询相匹配的文档。集合扫描很慢,可能会对应用程序的性能产生负面影响。通过适当的索引,MongoDB 可以限制其检查的文档数量。
提示
您还可以在更新操作、删除操作和某些聚合管道阶段中使用索引。
查询覆盖和性能
MongoDB 中的查询可以包含以下元素:
元素 | 必要性 | 用途 |
|---|---|---|
查询 | 必需 | 指定您要查找的字段和值。 |
选项 | Optional | 指定查询的执行方式。 |
投射 | Optional | 指定 MongoDB 返回的字段。 |
Sort | Optional | 指定 MongoDB 返回文档的顺序。 |
在同一索引中指定这些元素时,MongoDB 会直接从索引返回结果,这也称为覆盖查询。
重要
排序条件
您的排序条件必须与索引的顺序一致或相反。
考虑字段上的索引, name按升序 (AZ) 排列,而age按降序 (9-0) 排列:
name_1_age_-1
当您按以下任一方式对数据进行排序时,MongoDB 会使用此索引:
name升序,age降序name降序,age升序
但是,指定两个字段沿同一方向的排序顺序需要进行内存中排序。
如要了解如何确保索引涵盖查询标准和投影,请参阅查询覆盖。
操作注意事项
若要提高查询性能,请对查询中经常出现的字段和返回排序结果的操作创建索引。追踪索引内存和磁盘使用情况以进行容量规划,因为您添加的每个索引都会消耗磁盘空间和内存。此外,当写入操作更新索引字段时,MongoDB 还必须更新相关索引。
由于 MongoDB 支持动态模式,因此您的应用程序可以查询未知名称或任意名称的字段。MongoDB 4.2 引入了通配符索引,以帮助支持这些查询。通配符索引并不是为了取代基于工作负载的索引规划而设计的。
索引类型
MongoDB 支持多种索引类型来支持数据查询。以下各部分描述和演示了如何创建最常见的索引类型。要查看索引类型的完整列表,请参阅索引。
单字段索引
单字段索引包含对集合文档中字段的引用。
该索引提高了单字段查询和排序性能,并支持 TTL 索引,可在一定时间后从集合中自动删除文档。
注意
_id_ 索引是单字段索引的一个例子。当您创建新集合时,会在 _id 字段上自动创建此索引。
例子
以下示例在 sample_mflix.movies 集合中的 title 字段上按升序创建索引:
coll := client.Database("sample_mflix").Collection("movies") indexModel := mongo.IndexModel{ Keys: bson.D{{"title", 1}}, } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) } fmt.Println("Name of Index Created: " + name)
Name of Index Created: title_1
复合索引
复合索引包含对集合文档中多个字段的引用。此索引可提高查询和排序性能。
例子
以下示例在 sample_mflix.movies 集合中的 fullplot 和 title 字段上创建了复合索引:
coll := client.Database("sample_mflix").Collection("movies") indexModel := mongo.IndexModel{ Keys: bson.D{ {"fullplot", -1}, {"title", 1} } } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) } fmt.Println("Name of Index Created: " + name)
Name of Index Created: fullplot_-1_title_1
多键索引(数组字段索引)
多键索引使用与单字段索引和复合索引相同的语法。该索引提高了将数组字段指定为索引的查询的性能。
例子
以下示例在 sample_mflix.movies 集合中的 cast 字段上创建了一个多键索引:
coll := client.Database("sample_mflix").Collection("movies") indexModel := mongo.IndexModel{ Keys: bson.D{{"cast", -1}} } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) } fmt.Println("Name of Index Created: " + name)
Name of Index Created: cast_-1
MongoDB 搜索 和 MongoDB Vector 搜索索引
您可以使用Go驱动程序以编程方式管理MongoDB 搜索和MongoDB Vector 搜索搜索索引。
MongoDB搜索功能使您能够对MongoDB Atlas上托管的集合执行全文搜索。要了解有关 MongoDB 搜索 的更多信息,请参阅 MongoDB 搜索 文档。
MongoDB 向量搜索使您能够对存储在 Atlas 中的向量嵌入执行语义搜索。要学习;了解有关MongoDB Vector Search 的更多信息,请参阅MongoDB Vector Search 文档。
要详细了解如何运行 MongoDB 向量搜索搜索查询,请参阅运行 MongoDB 向量搜索搜索查询指南。
以下部分包含演示如何管理MongoDB Search 和MongoDB Vector Search 搜索索引的代码示例。
创建搜索索引
您可以通过向 SearchIndexView.CreateOne() 方法提供索引定义来创建 MongoDB 搜索 或 MongoDB 向量搜索 索引。
以下示例在 sample_mflix.movies集合的 plot字段上创建MongoDB 搜索索引:
// Sets the index name and type to "search" const indexName = "search_index" opts := options.SearchIndexes().SetName(indexName).SetType("search") // Defines the index definition searchIndexModel := mongo.SearchIndexModel{ Definition: bson.D{ {Key: "mappings", Value: bson.D{ {Key: "dynamic", Value: false}, {Key: "fields", Value: bson.D{ {Key: "plot", Value: bson.D{ {Key: "type", Value: "string"}, }}, }}, }}, }, Options: opts, } // Creates the index searchIndexName, err := coll.SearchIndexes().CreateOne(ctx, searchIndexModel) if err != nil { log.Fatalf("Failed to create the MongoDB Search index: %v", err) }
以下示例在 sample_mflix.embedded_movies集合中的 plot_embedding字段上创建MongoDB Vector Search索引:
// Defines the structs used for the index definition type vectorDefinitionField struct { Type string `bson:"type"` Path string `bson:"path"` NumDimensions int `bson:"numDimensions"` Similarity string `bson:"similarity"` Quantization string `bson:"quantization"` } type vectorDefinition struct { Fields []vectorDefinitionField `bson:"fields"` } // Sets the index name and type to "vectorSearch" const indexName = "vector_search_index" opts := options.SearchIndexes().SetName(indexName).SetType("vectorSearch") // Defines the index definition vectorSearchIndexModel := mongo.SearchIndexModel{ Definition: vectorDefinition{ Fields: []vectorDefinitionField{{ Type: "vector", Path: "plot_embedding", NumDimensions: 1536, Similarity: "dotProduct", Quantization: "scalar"}}, }, Options: opts, } // Creates the index searchIndexName, err := coll.SearchIndexes().CreateOne(ctx, vectorSearchIndexModel) if err != nil { log.Fatalf("Failed to create the MongoDB Vector Search index: %v", err) }
列出搜索索引
您可以使用 SearchIndexView.List() 方法通过指定索引名称来列出MongoDB Search 或MongoDB 向量搜索索引。
以下示例列出了指定MongoDB Search 或MongoDB 向量搜索索引的详细信息:
// Specifies the index to retrieve const indexName = "myIndex" opts := options.SearchIndexes().SetName(indexName) // Retrieves the details of the specified index cursor, err := coll.SearchIndexes().List(ctx, opts) // Prints the index details to the console as JSON var results []bson.D if err := cursor.All(ctx, &results); err != nil { log.Fatalf("Failed to unmarshal results to bson: %v", err) } res, err := json.Marshal(results) if err != nil { log.Fatalf("Failed to marshal results to json: %v", err) } fmt.Println(res)
更新搜索索引
您可以使用 SearchIndexView.UpdateOne() 方法通过指定索引名称和新索引定义来更新 MongoDB 搜索 或 MongoDB 向量搜索 索引。
以下示例通过提供索引名称和新的索引定义来更新MongoDB 向量搜索索引:
// Specifies the index name and the new index definition const indexName = "vector_search_index" type vectorDefinitionField struct { Type string `bson:"type"` Path string `bson:"path"` NumDimensions int `bson:"numDimensions"` Similarity string `bson:"similarity"` } type vectorDefinition struct { Fields []vectorDefinitionField `bson:"fields"` } definition := vectorDefinition{ Fields: []vectorDefinitionField{ { Type: "vector", Path: "plot_embedding", NumDimensions: 1536, Similarity: "cosine", Quantization: "scalar", }, }, } // Updates the specified index err := coll.SearchIndexes().UpdateOne(ctx, indexName, definition) if err != nil { log.Fatalf("Failed to update the index: %v", err) }
删除搜索索引
您可以使用 SearchIndexView.DropOne() 方法通过指定索引名称来删除 MongoDB 搜索 或 MongoDB 向量搜索 索引。
以下示例删除具有指定名称的MongoDB Search 或MongoDB Vector Search索引:
// Deletes the specified index err := coll.SearchIndexes().DropOne(ctx, "myIndex") if err != nil { log.Fatalf("Failed to delete the index: %v", err) }
MongoDB自动嵌入搜索索引模型
您可以使用Go驱动程序创建MongoDB Vector Search索引,该索引通过指定在 vectorSearch索引中使用 autoEmbed字段类型的索引定义,自动为文本字段生成向量嵌入。这允许MongoDB代表您调用 Voyage AI嵌入模型,并在插入或更新文档时保持嵌入同步。
在定义自动嵌入MongoDB Vector Search索引时,您需要指定一个 vectorSearch索引,该索引的定义文档包含必需的 fields数组。字段定义。该数组必须至少包含一个 autoEmbed字段,并且可以选择包含 filter 字段。此数组中的每个字段文档都使用以下选项:
字段选项 | 类型 | 说明 |
|---|---|---|
|
| 设置为 |
|
| 指定要嵌入的数据类型。要自动生成嵌入,您必须将其设立为 |
|
| 文档中要嵌入的文本字段的名称,示例 |
|
| 要使用的 Voyage AI嵌入模型的名称,示例 |
|
| 将您想要在 |
以下示例创建了一个名为 auto_embedding_index 的 vectorSearch索引,该索引完成以下操作:
使用
"voyage-4"模型自动为plot字段生成嵌入。在
runtime和year上添加可选过滤器字段,以便您可以通过这些值限制$vectorSearch查询。
以下示例展示了如何为索引模型定义定义结构体:
// Defines the structs for the index definition type autoEmbeddingField struct { Type string `bson:"type"` // "autoEmbed" Modality string `bson:"modality"` // "text" Path string `bson:"path"` // e.g. "plot" Model string `bson:"model"` // e.g. "voyage-4" } type filterField struct { Type string `bson:"type"` // "filter" Path string `bson:"path"` } type autoEmbeddingDefinition struct { Fields []any `bson:"fields"` }
以下示例展示了如何在 sample_mflix.movies集合上创建自动嵌入索引:
// Gets collection reference coll := client.Database("sample_mflix").Collection("movies") // Sets the index name and type to "vectorSearch" const indexName = "auto_embedding_index" opts := options.SearchIndexes(). SetName(indexName). SetType("vectorSearch") // Specifies the index definition def := autoEmbeddingDefinition{ Fields: []any{ autoEmbeddingField{ Type: "autoEmbed", Modality: "text", Path: "plot", Model: "voyage-4", }, // Optional filter fields filterField{ Type: "filter", Path: "runtime", }, filterField{ Type: "filter", Path: "year", }, }, } indexModel := mongo.SearchIndexModel{ Definition: def, Options: opts, } // Creates the index on the movies collection searchIndexName, err := coll.SearchIndexes().CreateOne(ctx, indexModel) if err != nil { log.Fatalf("Failed to create the MongoDB Vector Search auto-embedding index: %v", err) } fmt.Println("Created MongoDB Vector Search auto-embedding index:", searchIndexName)
要进一步学习如何查询自动嵌入的MongoDB 向量搜索索引,请参阅“查询自动嵌入索引”部分在“运行MongoDB 向量搜索 查询”指南中。
聚集索引
聚集索引可提高对集群化集合的插入、更新和删除操作的性能。集群化集合可以按聚集索引键值的顺序来存储文档。
要创建聚集索引,请在创建集合时指定聚集索引选项,其中_id字段指定为键,唯一字段为true 。
例子
以下示例对 db.tea 集合中的 _id 字段创建集群索引:
db := client.Database("db") cio := bson.D{{"key", bson.D{{"_id", 1}}}, {"unique", true}} opts := options.CreateCollection().SetClusteredIndex(cio) db.CreateCollection(context.TODO(), "tea", opts)
Text Indexes
文本索引支持对字符串内容进行文本查询。 此索引需要字符串字段或字符串大量。 MongoDB支持多种语言的文本搜索。创建索引时,您可以指定默认语言作为选项。
一个集合只能包含一个文本索引。如果要为多个文本字段创建文本索引,则必须创建复合索引。文本查询对复合索引中的所有文本字段运行。
提示
我们建议使用更强大的全文MongoDB 搜索和 Vector 搜索 索引来优化文本搜索。有关这些 Full Text Search 索引的更多信息,请参阅MongoDB 搜索和 MongoDB Vector Search 搜索索引部分。
例子
以下示例在 plot 字段上创建文本索引,并将 italian 作为 sample_mflix.movies 集合中的默认语言:
coll := client.Database("sample_mflix").Collection("movies") indexModel := mongo.IndexModel{Keys: bson.D{{"plot", "text"}, {"default_language", "italian"}}} name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) } fmt.Println("Name of Index Created: " + name)
Name of Index Created: plot_text
地理空间索引
MongoDB 支持使用 2dsphere 索引包含地理空间坐标数据的查询。2dsphere 索引必须在 GeoJSON 对象字段中。
此索引允许您执行以下操作:
查询地理空间数据以进行包含、交叉和邻近操作。
计算欧几里得平面上的距离,并使用 MongoDB 2.2 及更早版本中使用的“传统坐标对”语法。
例子
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 索引:
重要
尝试在地理空间索引所覆盖的字段上创建地理空间索引会导致错误。
indexModel := mongo.IndexModel{ Keys: bson.D{{"location.geo", "2dsphere"}} } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) } fmt.Println("Name of Index Created: " + name)
location.geo_2dsphere
Unique Indexes
唯一索引可确保索引字段不存储重复值。默认情况下,MongoDB 在创建集合期间会在 _id 字段上创建唯一索引。
要创建唯一索引,请指定要防止重复的字段或字段组合,并将 unique 选项设置为 true。
例子
以下示例在 theaterId 字段上创建唯一的降序索引:
indexModel := mongo.IndexModel{ Keys: bson.D{{"theaterId", -1}}, Options: options.Index().SetUnique(true), } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) } fmt.Println("Name of Index Created: " + name)
Name of Index Created: theaterId_-1
删除索引
您可以删除集合中的任何索引,但 _id字段上的默认唯一索引除外。 要删除索引,请将索引的名称传递给 DropOne() 方法。
title_1sample_mflix.movies以下示例从collection中删除名为 的索引:
coll := client.Database("sample_mflix").Collection("movies") err := coll.Indexes().DropOne(context.TODO(), "title_1") if err != nil { panic(err) }
更多信息
要了解有关所提及索引的更多信息,请参阅以下指南:
要了解有关提到的操作的更多信息,请参阅以下指南:
API 文档
要进一步学习;了解本指南中讨论的方法和相关方法,请参阅以下API文档: