Docs Home / Node.js Driver

Indexes for Query Optimization查询优化索引

Overview概述

Indexes are data structures that support the efficient execution of queries in MongoDB. They contain copies of parts of the data in documents to make queries more efficient.索引是支持MongoDB中高效执行查询的数据结构。它们包含文档中部分数据的副本,以提高查询效率。

Without indexes, MongoDB must scan every document in a collection to find the documents that match each query. These collection scans are slow and can negatively affect the performance of your application. 如果没有索引,MongoDB必须扫描集合中的每个文档,以找到与每个查询匹配的文档。这些集合扫描速度较慢,可能会对应用程序的性能产生负面影响。By using an index to limit the number of documents MongoDB scans, queries can be more efficient and therefore return faster.通过使用索引来限制MongoDB扫描的文档数量,查询可以更高效,因此返回速度更快。

Query Coverage and Performance查询覆盖率和性能

When you execute a query against MongoDB, your query can include three parts:当你对MongoDB执行查询时,你的查询可以包括三个部分:

  • Query criteria that specify one or more fields and values that you are looking for指定要查找的一个或多个字段和值的查询条件
  • Options that affect the query's execution, such as read concern影响查询执行的选项,例如读取关注
  • Projection criteria to specify the fields you want MongoDB to return (optional)用于指定您希望MongoDB返回的字段的投影标准(可选)

When all the fields specified in the query criteria and projection of a query are indexed, MongoDB returns results directly from the index without scanning any documents in the collection or loading them into memory.当查询条件和查询投影中指定的所有字段都被索引时,MongoDB直接从索引中返回结果,而无需扫描集合中的任何文档或将其加载到内存中。

For more information on how to ensure your index covers your query criteria and projection, see the MongoDB manual articles on query coverage and index intersection.有关如何确保索引覆盖查询条件和投影的更多信息,请参阅MongoDB手册中关于查询覆盖率索引交集的文章。

Operational Considerations操作注意事项

To improve query performance, build indexes on fields that appear often in your application's queries and operations that return sorted results. Each index that you add consumes disk space and memory when active, so it might be necessary to track index memory and disk usage for capacity planning. In addition, when a write operation updates an indexed field, MongoDB also updates the related index.为了提高查询性能,请在应用程序的查询和返回排序结果的操作中经常出现的字段上构建索引。您添加的每个索引在活动时都会消耗磁盘空间和内存,因此可能需要跟踪索引内存和磁盘使用情况以进行容量规划。此外,当写操作更新索引字段时,MongoDB也会更新相关索引。

For more information on designing your data model and choosing indexes appropriate for your application, see the MongoDB Server documentation on Indexing Strategies and Data Modeling and Indexes.有关设计数据模型和选择适合应用程序的索引的更多信息,请参阅MongoDB Server关于索引策略数据建模与索引的文档。

List Indexes列出索引

You can use the listIndexes() method to list all the indexes for a collection. 您可以使用listIndexes()方法列出集合的所有索引。The listIndexes() method takes an optional ListIndexesOptions parameter. listIndexes()方法接受可选的ListIndexesOptions参数。The listIndexes() method returns an object of type ListIndexesCursor.listIndexes()方法返回一个ListIndexesCursor类型的对象。

The following code uses the listIndexes() method to list all the indexes in a collection:以下代码使用listIndexes()方法列出集合中的所有索引:

// List the indexes on the collection and output them as an array列出集合上的索引并将其作为数组输出
const result = await collection.listIndexes().toArray();

// Print the list of indexes打印索引列表
console.log("Existing indexes:\n");
for(const doc in result){
console.log(doc);
}

Index Types索引类型

MongoDB supports several different index types to support querying your data. The following sections describe the most common index types and provide sample code for creating each index type.MongoDB支持多种不同的索引类型来支持查询您的数据。以下部分描述了最常见的索引类型,并提供了创建每种索引类型的示例代码。

Single Field Indexes单字段索引

Single field indexes are indexes that improve performance for queries that specify ascending or descending sort order on a single field of a document.单字段索引是提高查询性能的索引,这些查询在文档的单个字段上指定升序或降序排序。

The following example uses the createIndex() method to create an ascending order index on the title field in the movies collection in the sample_mflix database.以下示例使用createIndex()方法在sample_mflix数据库中movies集合的标题字段上创建升序索引。

const database = client.db("sample_mflix");
const movies = database.collection("movies");

// Create an ascending index on the "title" field in the "movies" collection.在“电影”集合中的“标题”字段上创建一个升序索引。
const result = await movies.createIndex({ title: 1 });
console.log(`Index created: ${result}`);

The following is an example of a query that is covered by the index created above.以下是上面创建的索引所涵盖的查询示例。

// Define the query parameters定义查询参数
const query = { title: "Batman" }
const sort = { title: 1 };
const projection = { _id: 0, title: 1 };
// Execute the query using the defined parameters使用定义的参数执行查询
const cursor = movies
.find(query)
.sort(sort)
.project(projection);

for await (const doc of cursor) {
console.log(doc);
}

To learn more, see Single Field Indexes.要了解更多信息,请参阅单字段索引

Compound Indexes复合指数

Compound indexes are indexes that improve performance for queries that specify ascending or descending sort order for multiple fields of a document. You must specify the direction (ascending or descending) for each field in the index.复合索引是提高查询性能的索引,这些查询为文档的多个字段指定升序或降序排序。您必须为索引中的每个字段指定方向(升序或降序)。

The following example uses the createIndex() method to create a compound index on the type and genre fields in the movies collection in the sample_mflix database.以下示例使用createIndex()方法对sample_mflix数据库中movies集合中的type(类型)和genre(流派)字段创建复合索引。

// Connect to the "sample_mflix" database连接到“sample_mflix”数据库
const database = client.db("sample_mflix");
// Access the database's "movies" collection访问数据库的“电影”集合
const movies = database.collection("movies");

// Create an ascending index on the "type" and "genre" fields in the "movies" collection.在"movies"集合中的"type"和"genre"字段上创建一个升序索引。
const result = await movies.createIndex({ type: 1, genre: 1 });
console.log(`Index created: ${result}`);

The following is an example of a query that is covered by the index created above.以下是上面创建的索引所涵盖的查询示例。

// Define a query to find movies in the "Drama" genre定义一个查询以查找“戏剧”类型的电影
const query = { type: "movie", genre: "Drama" };
// Define sorting criteria for the query results定义查询结果的排序条件
const sort = { type: 1, genre: 1 };
// Include only the type and genre fields in the query results在查询结果中仅包含类型和流派字段
const projection = { _id: 0, type: 1, genre: 1 };

// Execute the query using the defined criteria and projection使用定义的条件和投影执行查询
const cursor = movies
.find(query)
.sort(sort)
.project(projection);

for await (const doc of cursor) {
console.log(doc);
}

To learn more, see Compound Indexes.要了解更多信息,请参阅复合索引

Multikey Indexes (Indexes on Array Fields)多键索引(数组字段上的索引)

Multikey indexes are indexes that improve the performance of queries on fields that contain array values.多键索引是提高对包含数组值的字段的查询性能的索引。

You can create a multikey index on a field with an array value by calling the createIndex() method. The following code creates an ascending index on the cast field in the movies collection of the sample_mflix database:您可以通过调用createIndex()方法在具有数组值的字段上创建多键索引。以下代码在sample_mflix数据库的movies集合中的cast字段上创建了一个升序索引:

const database = client.db("sample_mflix");
const movies = database.collection("movies");

// Create a multikey index on the "cast" field in the "movies" collection在"movies"集合中的"cast"字段上创建多键索引
const result = await movies.createIndex({ cast: 1 });

The following code queries the multikey index to find documents in which the cast field value contains "Viola Davis":以下代码查询多键索引,以查找cast(演员)字段值包含"Viola Davis"的文档:

const query = { cast: "Viola Davis" };
const projection = { _id: 0, cast: 1 , title: 1 };

// Perform a find operation with the preceding filter and projection使用前面的筛选器和投影执行查找操作
const cursor = movies
.find(query)
.project(projection);

for await (const doc of cursor) {
console.log(doc);
}

Multikey indexes behave differently from non-multikey indexes in terms of query coverage, index bound computation, and sort behavior. For a full explanation of multikey indexes, including a discussion of their behavior and limitations, see the Multikey Indexes page in the MongoDB Server manual.多键索引在查询覆盖率、索引边界计算和排序行为方面与非多键索引的行为不同。有关多键索引的完整解释,包括对其行为和限制的讨论,请参阅MongoDB Server手册中的多键索引页面。

Clustered Indexes聚集索引

Clustered indexes are indexes that improve the performance of insert, update, and delete operations on clustered collections. Clustered collections store documents ordered by the clustered index key value.聚集索引是提高聚集集合上插入、更新和删除操作性能的索引。聚集集合存储按聚集索引键值排序的文档。

To create a clustered index, specify the clusteredIndex option in the CollectionOption. The clusteredIndex option must specify the _id field as the key and the unique field as true.要创建聚集索引,请在CollectionOption中指定clusteredIndex选项。clusteredIndex选项必须将_id字段指定为键,将唯一字段指定为true

The following example uses the createCollection() method to create a clustered index on the _id field in the vendors collection of the tea database.以下示例使用createCollection()方法在tea(茶叶)数据库的vendors(供应商)集合中的_id字段上创建聚集索引。

const db = client.db('tea');
await db.createCollection('ratings', {
clusteredIndex: {
key: { _id: 1 },
unique: true
}
});

To learn more, see Clustered Indexes and Clustered Collections.要了解更多信息,请参阅聚集索引聚集集合

Text Indexes全文索引

Text indexes support text queries on string content. These indexes can include any field whose value is a string or an array of string elements.文本索引支持对字符串内容进行文本查询。这些索引可以包括其值为字符串或字符串元素数组的任何字段。

MongoDB supports text queries for various languages, so you can specify the default language as an option when creating the index. You can also specify a weight option to prioritize certain text fields in your index. MongoDB支持各种语言的文本查询,因此您可以在创建索引时指定默认语言作为选项。您还可以指定权重选项,以对索引中的某些文本字段进行优先级排序。These weights denote the significance of fields relative to the other indexed fields.这些权重表示字段相对于其他索引字段的重要性。

To learn more about text queries, see our guide on text queries.要了解有关文本查询的更多信息,请参阅文本查询指南。

The following example uses the createIndex() method to perform the following actions:以下示例使用createIndex()方法执行以下操作:

  • Create a text index on the title and body fields in the blogPosts collectionblogPosts集合的text(标题)和body(正文)字段上创建text索引
  • Specify english as the default language指定english为默认语言
  • Set the field weight of body to 10 and title to 3body的字段权重设置为10,将title设置为3
// Get the database and collection on which to create the index获取要在其上创建索引的数据库和集合 
const myDB = client.db("testDB");
const myColl = myDB.collection("blogPosts");

// Create a text index on the "title" and "body" fields在“标题”和“正文”字段上创建文本索引
const result = await myColl.createIndex(
{ title: "text", body: "text" },
{
default_language: "english",
weights: { body: 10, title: 3 }
}
);

The following query uses the text index created in the preceding code:以下查询使用在前面的代码中创建的文本索引:

// Query for documents where body or title contain "life ahead"查询正文或标题中包含“未来生活”的文档
const query = { $text: { $search: "life ahead" } };

// Show only the title field仅显示标题字段
const projection = { _id: 0, title: 1 };

// Execute the find operation执行查找操作
const cursor = myColl.find(query).project(projection);

for await (const doc of cursor) {
console.log(doc);
}

To learn more about text indexes, see Text Indexes in the Server manual.要了解有关文本索引的更多信息,请参阅服务器手册中的文本索引

Geospatial Indexes地理空间索引

MongoDB supports queries of geospatial coordinate data using 2dsphere indexes. With a 2dsphere index, you can query the geospatial data for inclusion, intersection, and proximity. MongoDB支持使用2dsphere索引查询地理空间坐标数据。使用2dsphere索引,您可以查询地理空间数据的包含、交叉和邻近。For more information on querying geospatial data with the MongoDB Node.js driver, read our Search Geospatial guide.有关使用MongoDB Node.js驱动程序查询地理空间数据的更多信息,请阅读搜索地理空间指南。

To create a 2dsphere index, you must specify a field that contains only GeoJSON objects. For more details on this type, see the MongoDB Server manual page on GeoJSON objects.要创建2dsphere索引,您必须指定一个仅包含GeoJSON对象的字段。有关此类型的更多详细信息,请参阅关于GeoJSON对象的MongoDB服务器手册页。

The location.geo field in following sample document from the theaters collection in the sample_mflix database is a GeoJSON Point object that describes the coordinates of the theater:sample_mflix数据库中theaters集合的以下示例文档中的location.geo字段是一个描述剧院坐标的GeoJSON Point对象:

{
"_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
]
}
}
}

The following example uses the createIndexes() method to create a 2dsphere index on the location.geo field in the theaters collection in the sample_mflix database to enable geospatial searches.以下示例使用createIndexes()方法在sample_mflix数据库的剧院集合中的location.geo字段上创建2dsphere索引,以启用地理空间搜索。

const database = client.db("sample_mflix");
const movies = database.collection("movies");

/* Create a 2dsphere index on the "location.geo" field in the "movies" collection在“movies”集合中的“location.geo”字段上创建2dsphere索引 */
const result = await movies.createIndex({ "location.geo": "2dsphere" });

// Print the result of the index creation打印索引创建的结果
console.log(`Index created: ${result}`);

MongoDB also supports 2d indexes for calculating distances on a Euclidean plane and for working with the "legacy coordinate pairs" syntax used in MongoDB 2.2 and earlier. MongoDB还支持2d索引,用于计算欧几里德平面上的距离,以及使用MongoDB 2.2及更早版本中使用的“遗留坐标对”语法。To learn more, see Geospatial Queries.要了解更多信息,请参阅地理空间查询

Unique Indexes唯一索引

Unique indexes ensure that the indexed fields do not store duplicate values. By default, MongoDB creates a unique index on the _id field during the creation of a collection. 唯一索引可确保索引字段不存储重复值。默认情况下,MongoDB在创建集合时在_id字段上创建一个唯一索引。To create a unique index, specify the field or combination of fields that you want to prevent duplication on and set the unique option to true.要创建唯一索引,请指定要防止重复的字段或字段组合,并将unique选项设置为true

The following example uses the createIndex() method to create a unique index on the theaterId field in the theaters collection of the sample_mflix database.以下示例使用createIndex()方法在sample_mflix数据库的theaters集合中的theaterId字段上创建唯一索引。

const database = client.db("sample_mflix");
const movies = database.collection("movies");

// Create a unique index on the "theaterId" field in the "theaters" collection.在“剧院”集合中的“theaterId”字段上创建一个唯一索引。
const result = await movies.createIndex({ theaterId: 1 }, { unique: true });
console.log(`Index created: ${result}`);

If you attempt to perform a write operation that stores a duplicate value that violates the unique index, MongoDB will throw an error that resembles the following:如果您尝试执行存储违反唯一索引的重复值的写入操作,MongoDB将抛出类似以下内容的错误:

E11000 duplicate key error index

To learn more, see Unique Indexes.要了解更多信息,请参阅唯一索引

MongoDB Search and MongoDB Vector Search IndexesMongoDB搜索和MongoDB向量搜索索引

You can programmatically manage your MongoDB Search and Atlas Vector Search indexes by using the Node.js driver.您可以使用Node.js驱动程序以编程方式管理MongoDB搜索和Atlas矢量搜索索引。

The MongoDB Search feature enables you to perform full-text searches on collections hosted on MongoDB Atlas. To learn more about Atlas Search, see the MongoDB Search documentation.MongoDB搜索功能使您能够对MongoDB Atlas上托管的集合执行全文搜索。要了解有关Atlas搜索的更多信息,请参阅MongoDB搜索文档。

MongoDB Vector Search enables you to perform semantic searches on vector embeddings stored in Atlas. To learn more about Atlas Vector Search, see the MongoDB Vector Search documentation.MongoDB矢量搜索使您能够对存储在Atlas中的矢量嵌入执行语义搜索。要了解有关Atlas矢量搜索的更多信息,请参阅MongoDB矢量搜索文档。

To learn more about how to run a MongoDB Search or MongoDB Vector Search query, see the Run a MongoDB Search Query or Run a MongoDB Vector Search Query guide.要了解有关如何运行MongoDB搜索或MongoDB矢量搜索查询的更多信息,请参阅《运行MongoDB搜索查询》《运行MongoDB矢量搜索搜索查询》指南。

The following sections contain code examples that demonstrate how to manage MongoDB Search and MongoDB Vector Search indexes.以下部分包含演示如何管理MongoDB搜索和MongoDB向量搜索索引的代码示例。

Create a Search Index创建搜索索引

You can use the createSearchIndex() and createSearchIndexes() methods to create new MongoDB Search and MongoDB Vector Search indexes.您可以使用createSearchIndex()createSearchIndexes()方法创建新的MongoDB搜索和MongoDB向量搜索索引。

The following code shows how to use the createSearchIndex() method to create a MongoDB Search index called search1:以下代码显示了如何使用createSearchIndex()方法创建名为search1的MongoDB搜索索引:

// Creates a MongoDB Search index创建MongoDB搜索索引
const index1 = {
name: "search1",
definition: {
"mappings": {
"dynamic": true
}
}
}
await collection.createSearchIndex(index1);

When connecting to MongoDB Server v6.0.11 and later, you can use the driver to create a MongoDB Vector Search index by specifying vectorSearch in the type field of the index definition.当连接到MongoDB Server v6.0.11及更高版本时,您可以使用驱动程序通过在索引定义的type字段中指定vectorSearch来创建MongoDB矢量搜索索引。

The following code shows how to use the createSearchIndex() method to create a MongoDB Vector Search index:以下代码显示了如何使用createSearchIndex()方法创建MongoDB矢量搜索索引:

// Creates a MongoDB Vector Search index创建MongoDB矢量搜索索引
const vectorSearchIdx = {
name: "vsidx1",
type: "vectorSearch",
definition: {
fields: [{
type: "vector",
numDimensions: 384,
path: "summary",
similarity: "dotProduct"
}]
}
}

await collection.createSearchIndex(vectorSearchIdx);

List Search Indexes列出搜索索引

You can use the listSearchIndexes() method to return a cursor that contains the MongoDB Search and MongoDB Vector Search indexes of a given collection. 您可以使用listSearchIndexes()方法返回一个游标,该游标包含给定集合的MongoDB搜索和MongoDB向量搜索索引。The listSearchIndexes() method takes an optional string parameter, name, to return only the indexes with matching names. listSearchIndexes()方法接受一个可选的字符串参数name,仅返回具有匹配名称的索引。It also takes an optional aggregateOptions parameter.它还需要一个可选的aggregateOptions参数。

The following code uses the listSearchIndexes() method to list the MongoDB Search and MongoDB Vector Search indexes in a collection:以下代码使用listSearchIndexes()方法列出集合中的MongoDB搜索和MongoDB向量搜索索引:

// Lists search indexes列出搜索索引
const result = await collection.listSearchIndexes().toArray();
console.log("Existing search indexes:\n");
for (const doc in result) {
console.log(doc);
}

Update a Search Index更新搜索索引

You can use the updateSearchIndex() method to update a MongoDB Search or MongoDB Vector Search index by providing a new index definition.您可以使用updateSearchIndex()方法通过提供新的索引定义来更新MongoDB搜索或MongoDB向量搜索索引。

The following code shows how to use the updateSearchIndex() method to update a MongoDB Search index called search1 to change the type of the description field to a string:以下代码显示了如何使用updateSearchIndex()方法更新名为search1的MongoDB搜索索引,将描述字段的类型更改为字符串:

// Updates a search index更新搜索索引
const index2 = {
"mappings": {
"dynamic": true,
"fields": {
"description": {
"type": "string"
}
}
}
}
await collection.updateSearchIndex("search1", index2);

Drop a Search Index删除搜索索引

You can use the dropSearchIndex() method to remove a MongoDB Search or MongoDB Vector Search index.您可以使用dropSearchIndex()方法删除MongoDB搜索或MongoDB向量搜索索引。

The following code shows how to use the dropSearchIndex() method to remove an index called search1:以下代码显示了如何使用dropSearchIndex()方法删除名为search1的索引:

// Drops (deletes) a search index删除搜索索引
await collection.dropSearchIndex("search1");