Docs 菜单
Docs 主页
/ / /
Go 驱动程序
/

索引

在此页面上

  • Overview
  • 查询覆盖和性能
  • 操作注意事项
  • 索引类型
  • 单字段索引
  • 复合索引
  • 多键索引(数组字段索引)
  • 聚集索引
  • Text Indexes
  • 地理空间索引
  • Unique Indexes
  • 删除索引
  • 更多信息
  • API 文档

在本指南中,您可以学习如何在 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 升序

指定 nameage 升序或 nameage 降序排序需要进行内存中排序。

如要了解如何确保索引涵盖查询标准和投影,请参阅查询覆盖

若要提高查询性能,请对查询中经常出现的字段和返回排序结果的操作创建索引。追踪索引内存和磁盘使用情况以进行容量规划,因为您添加的每个索引都会消耗磁盘空间和内存。此外,当写入操作更新索引字段时,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 集合中的 fullplottitle 字段上创建了复合索引:

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

聚集索引可提高对集群化集合的插入、更新和删除操作的性能。集群化集合可以按聚集索引键值的顺序来存储文档。

要创建聚集索引,请在创建集合时指定聚集索引选项,其中_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)

文本索引支持对字符串内容进行文本搜索查询。此索引需要字符串字段或字符串数组。MongoDB 支持多种语言的文本搜索。在创建索引时,可以指定默认语言作为选项。

一个集合只能包含一个文本索引。如果要为多个文本字段创建文本索引,必须创建复合索引。文本搜索在复合索引内的所有文本字段上运行。

提示

文本索引不同于功能更强大的 Atlas Full Text Search 索引。我们建议 Atlas 用户使用 Atlas 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

唯一索引可确保索引字段不存储重复值。默认情况下,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() 方法。

以下示例删除sample_mflix.movies集合中title字段的升序索引:

coll := client.Database("sample_mflix").Collection("movies")
res, err := coll.Indexes().DropOne(context.TODO(), "title_1")
if err != nil {
panic(err)
}
fmt.Println(res)
{"nIndexesWas": {"$numberInt":"2"}}

要了解有关所提及索引的更多信息,请参阅以下指南:

要了解有关提到的操作的更多信息,请参阅以下指南:

  • 指定查询

  • 修改文档

  • Delete Documents

要进一步了解本指南所讨论的任何方法,请参阅以下 API 文档:

后退

聚合(Aggregation)