对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

使用索引优化查询

在本指南中,您可以学习如何使用 MongoDB Scala 驱动程序创建和管理索引。

MongoDB 中的索引支持高效执行查询。如果没有索引,MongoDB 必须执行集合扫描,读取集合中的每个文档以找到查询匹配项。集合扫描会降低应用程序的性能。如果查询存在适当的索引,MongoDB 就可以使用该索引来限制必须检查的文档。

索引还可实现以下功能:

提示

MongoDB also uses indexes when finding documents for update operations and delete operations. Certain stages in the aggregation pipeline also use indexes to improve performance.

对 MongoDB 执行查询时,您的命令可以包含以下元素:

  • 用于指定您要查找的字段和值的查询条件

  • 影响查询执行的选项,例如读关注

  • 指定 MongoDB 返回的字段的投影条件(可选)

  • 指定返回文档顺序的排序标准(可选)

当查询、投影和排序中的所有字段均位于同一索引时,MongoDB 会直接从索引返回结果。此过程称为覆盖查询。

重要

排序顺序

排序条件必须与索引的顺序一致或相反。

举例来说,以下索引指定字段 name 按升序 (AZ) 排序而 {2} 按降序 (9-0) 排序:

name_1_age_-1

当您按以下任一方式对数据进行排序时,MongoDB 会使用此索引:

  • name 升序, age降序

  • name 降序,age 升序

将 name 和 age 都指定为升序或都指定为降序需要进行内存中排序。

For more information about index coverage, see Query Optimization in the MongoDB Server manual.

以下指南描述了如何优化应用程序使用索引的方式:

  • 若要提高查询性能,请对应用程序查询中经常出现的字段以及其他操作返回的排序结果中经常出现的字段构建索引。

  • 追踪索引内存和磁盘使用情况以进行容量规划,因为您添加的每个索引在活动时都会消耗磁盘空间和内存。

  • 避免添加不常用的索引。请注意,当写入操作更新索引的字段时,MongoDB 会更新相关索引。

Since MongoDB supports dynamic schemas, applications can query against fields whose names cannot be known in advance or are arbitrary. MongoDB 4.2 introduced wildcard indexes to help support these queries. Wildcard indexes are not designed to replace workload-based index planning.

有关设计数据模型和选择适合您应用程序的索引的更多信息,请参阅 MongoDB 服务器文档中的索引策略和数据建模和索引部分。

您可以使用以下示例应用程序来测试此页面上的代码。 要使用示例应用程序,请执行以下步骤:

  1. 确保项目中安装了Scala驱动程序。请参阅下载和安装指南以学习;了解更多信息。

  2. 复制以下代码并将其粘贴到新的.scala文件中。

  3. 从此页面复制代码示例,并将其粘贴到文件中的指定行。

import org.mongodb.scala._
import org.mongodb.scala.model.SearchIndexModel
import java.util.concurrent.TimeUnit
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import org.mongodb.scala.model.Indexes
object SearchIndexes {
def main(args: Array[String]): Unit = {
// Create a new client and connect to the server
val mongoClient = MongoClient("<connection string URI>")
val database = mongoClient.getDatabase("<database name>")
val collection = database.getCollection("<collection name>")
// Start example code here
// End example code here
Thread.sleep(1000)
mongoClient.close()
}
}

The examples in this guide use the movies collection in the sample_mflix database from the Atlas sample datasets. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started with Atlas.

MongoDB 支持多种不同的索引类型来支持数据查询。 以下部分描述了最常见的索引类型,并提供了创建每种索引类型的示例代码。 有关索引类型的完整列表,请参阅 MongoDB Server手册中的 索引 。

单字段索引是对集合文档中的单字段进行引用的索引。其提高了单字段查询和排序性能,并支持 TTL 索引,可在一定时间后或特定时钟时间自动从集合中删除文档。

注意

_id_ 索引是单字段索引的一个示例。创建新集合时,会在 _id 字段上自动创建此索引。

以下示例在指定字段上创建一个升序索引:

val index = Indexes.ascending("<field name>")
val observable = collection.createIndex(index)
Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))

要运行本节中的以下示例,必须在文件中包含以下 import 声明:

import org.mongodb.scala._
import org.mongodb.scala.model.Indexes
import org.mongodb.scala.model.IndexOptions._
import org.mongodb.scala.model.Filters._
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.util.{Failure, Success}
import java.util.concurrent.TimeUnit

使用createIndex()方法创建单字段索引。 以下示例在title字段上按升序创建索引:

val index = Indexes.ascending("title")
val observable = collection.createIndex(index)
Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))

您可以使用 listIndexes() 方法验证索引是否已创建。 您应该会在列表中看到 title 的索引,如以下输出所示:

collection.listIndexes().subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))
{"v": 2, "key": {"title": 1}, "name": "title_1"}

以下是在 title字段上创建的索引涵盖的查询示例:

val filter = equal("title", "Sweethearts")
collection.find(filter).first().subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))

复合索引包含对集合文档中多个字段的引用,从而提高查询和排序性能。

提示

To learn more about index prefixes see the Index Prefixes entry in the MongoDB Server manual.

以下示例在两个指定字段上创建复合索引。

val index = Indexes.compoundIndex(
Indexes.descending("<field name 1>"),
Indexes.ascending("<field name 2>")
)
val observable = collection.createIndex(index)
Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))

要运行本节中的以下示例,必须在文件中包含以下 import 声明:

import org.mongodb.scala._
import org.mongodb.scala.model.Indexes
import org.mongodb.scala.model.IndexOptions._
import org.mongodb.scala.model.Filters._
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.util.{Failure, Success}
import java.util.concurrent.TimeUnit

使用 createIndex() 方法创建复合索引。 以下示例按降序对 runtime字段创建索引,并按升序对 year字段创建索引:

val index = Indexes.compoundIndex(Indexes.descending("runtime"),
Indexes.ascending("year"))
val observable = collection.createIndex(index)
Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))

您可以使用 listIndexes() 方法验证索引是否已创建。 您应该在列表中看到 runtime 和 year 的索引,如以下输出所示:

collection.listIndexes().subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))
{"v": 2, "key": {"runtime": -1, "year": 1}, "name": "runtime_-1_year_1"}

以下是在 runtime 和 year 字段上创建的索引涵盖的查询示例:

val filter = and(gt("runtime", 80), gt("year", 1999))
collection.find(filter).first().subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))

Multikey indexes are indexes that improve the performance of queries on array-valued fields. You can create a multikey index on a collection by using the createIndex() method and the same syntax that you use to create a single field index.

创建多键索引时,必须指定以下详细信息:

  • 要在其上创建索引的字段

  • 每个字段的排序顺序(升序或降序)

以下示例在指定的数组值字段上创建多键索引:

val index = Indexes.ascending("<field name>")
val observable = collection.createIndex(index)
Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))

要运行本节中的以下示例,必须在文件中包含以下 import 声明:

import org.mongodb.scala._
import org.mongodb.scala.model.Indexes
import org.mongodb.scala.model.IndexOptions._
import org.mongodb.scala.model.Filters._
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.util.{Failure, Success}
import java.util.concurrent.TimeUnit

使用 createIndex() 方法创建多键索引。 以下示例在 cast字段上按升序创建索引:

val index = Indexes.ascending("cast")
val observable = collection.createIndex(index)
Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))

您可以通过调用 listIndexes() 方法验证索引是否已创建。 您应该会在列表中看到 cast 的索引,如以下输出所示:

collection.listIndexes().subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))
{"v": 2, "key": {"cast": 1}, "name": "cast_1"}

以下是在 cast字段上创建的索引涵盖的查询示例:

val filter = and(equal("cast", "Aamir Khan"), equal("cast", "Kajol"))
collection.find(filter).first().subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))

MongoDB Search enables you to perform full-text searches on collections hosted on MongoDB Atlas. MongoDB Search indexes specify the behavior of the search and which fields to index.

MongoDB Vector Search 使您能够对存储在 MongoDB 中的向量嵌入执行语义搜索。要了解有关 MongoDB Vector Search 的更多信息,请参阅 MongoDB Vector Search 概述。

您可以在集合上调用以下方法来管理MongoDB Search 和MongoDB Vector Search 索引:

  • createSearchIndex()

  • createSearchIndexes()

  • listSearchIndexes()

  • updateSearchIndex()

  • dropSearchIndex()

注意

上述索引管理方法异步运行,并且可能会在确认其成功运行之前返回。要确定索引的当前状态,请调用 listSearchIndexes() 方法。

您可以使用 createSearchIndex() 和 createSearchIndexes() 方法创建一个或多个 MongoDB Search 或 MongoDB 向量搜索索引。createSearchIndexes() 方法接受索引定义列表,这使您可以在一次调用中创建多个索引,并为每个索引指定索引类型。

以下代码示例展示了如何创建MongoDB搜索索引:

val index = Document("mappings" -> Document("dynamic" -> true))
collection.createSearchIndex("<index name>", index)
.subscribe((result: String) => ())

使用 createSearchIndexes() 方法创建多个 MongoDB Search 或 MongoDB Vector Search 索引。

以下代码示例展示了如何在一次调用中创建 MongoDB Search 和 MongoDB Vector Search 搜索索引:

val searchIdxMdl = SearchIndexModel(
Option("searchIdx"),
Document("analyzer" -> "lucene.standard", "mappings" -> Document("dynamic" -> true)),
Option(SearchIndexType.search())
)
val vectorSearchIdxMdl = SearchIndexModel(
Option("vsIdx"),
Document(
"fields" -> List(
Document("type" -> "vector", "path" -> "embeddings", "numDimensions" -> 1536, "similarity" -> "dotProduct")
)
),
Option(SearchIndexType.vectorSearch())
)
collection.createSearchIndexes(List(searchIdxMdl, vectorSearchIdxMdl))
.subscribe((result: String) => ())

To learn more about the syntax used to define MongoDB Search indexes, see the Index Reference guide in the Atlas manual.

您可以使用 listSearchIndexes() 方法返回集合中的所有 MongoDB 搜索索引。

以下代码示例演示如何通过订阅 listSearchIndexes() 方法返回的 Observable 来打印集合中的搜索索引列表:

collection.listSearchIndexes()
.subscribe((result: Document) => println(result.toJson()))

您可以使用 updateSearchIndex() 方法更新 MongoDB 搜索索引。

以下代码展示如何更新搜索索引:

val updateIndex = Document("mappings" -> Document("dynamic" -> false))
collection.updateSearchIndex("<index to update>", updateIndex)
.subscribe((result: Unit) => ())

您可以使用 dropSearchIndex() 方法删除 MongoDB 搜索索引。

警告

删除搜索索引和集群是不可逆的

删除搜索索引和相关集群是永久操作。MongoDB 不支持恢复已删除的搜索索引或数据。在继续操作之前,请确保您已采取了适当措施,例如创建备份,以避免数据丢失。

MongoDB 不支持恢复已删除的搜索索引或数据的请求。您负责数据完整性和配置。

以下代码展示了如何从集合中删除搜索索引:

collection.dropSearchIndex("<index name>")
.subscribe((result: Unit) => ())

以下示例在包含GeoJSON对象的指定字段上创建2 dsphere索引:

val observable = collection.createIndex(Indexes.geo2dsphere("<2d index>"))
Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))

For more information on 2dsphere indexes, see the 2dsphere Indexes guide in the MongoDB Server manual.

有关GeoJSON类型的更多信息,请参阅MongoDB Server手册中的GeoJSON对象指南。

您可以删除针对 _id 字段的所有未使用索引,但默认唯一索引除外。

以下示例删除具有指定名称的索引:

val observable = collection.dropIndex("<index name>")
Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))

要学习;了解有关本指南中使用的方法或对象的更多信息,请参阅以下API文档: