文档菜单
文档首页
/ / /
Node.js 驱动
/

索引

本页内容

  • 概述
  • 查询覆盖率和性能
  • 操作注意事项
  • 列表索引
  • 索引类型
  • 单字段索引
  • 复合索引
  • 多键索引(数组字段的索引)
  • 聚集索引
  • 文本索引
  • 地理空间索引
  • 唯一索引
  • 搜索索引
  • 创建搜索索引
  • 列出搜索索引
  • 更新搜索索引
  • 删除搜索索引

索引是支持在MongoDB中高效执行查询的数据结构。它们包含文档中数据部分副本,以提高查询效率。

没有索引,MongoDB必须扫描集合中的每个文档以找到与每个查询匹配的文档。这些集合扫描很慢,可能会影响应用程序的性能。通过使用索引限制MongoDB扫描的文档数,查询可以更高效,因此返回更快。

当您在MongoDB上执行查询时,您的查询可以包含三个部分

  • 查询条件,指定一个或多个您要查找的字段和值

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

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

当查询条件中指定的所有字段以及查询的投影都索引时,MongoDB可以直接从索引返回结果,而无需扫描集合中的任何文档或将它们加载到内存中。

有关如何确保您的索引覆盖查询条件和投影的更多信息,请参阅MongoDB手册中的以下文章:查询覆盖索引交集

为了提高查询性能,在经常出现在应用程序查询和返回排序结果的字段上建立索引。每个添加的索引在活动状态下都会消耗磁盘空间和内存,因此可能需要跟踪索引的内存和磁盘使用情况以进行容量规划。此外,当写入操作更新索引字段时,MongoDB 也会更新相关索引。

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

您可以使用listIndexes() 方法用于列出集合的所有索引。该 listIndexes() 方法可以接受一个可选的 ListIndexesOptions 参数。该 listIndexes() 方法返回一个类型为 ListIndexesCursor 的对象。

以下代码使用 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);
}

MongoDB支持多种不同的索引类型,以支持对数据进行查询。以下各节描述了最常见的索引类型,并提供了创建每种索引类型的示例代码。

单字段索引是提高对指定升序或降序排序的单个字段进行查询的查询性能的索引。

以下示例使用createIndex()方法在sample_mflix数据库中的movies集合的title字段上创建升序索引。

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}`);

以下是一个由上面创建的索引覆盖的查询示例。

// 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);

了解更多信息,请参阅单字段索引。

复合索引 是针对指定多个文档字段升序或降序排序的查询来提高性能的索引。您必须指定索引中每个字段的排序方向(升序或降序)。

以下示例使用 createIndex() 方法在 sample_mflix 数据库中 movies 集合的 typegenre 字段上创建复合索引。

// Connect to the "sample_mflix" database
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.
const result = await movies.createIndex({ type: 1, genre: 1 });
console.log(`Index created: ${result}`);

以下是一个由上面创建的索引覆盖的查询示例。

// 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);

欲了解更多信息,请参阅 复合索引。

多键索引 是针对包含数组值的字段进行查询以提高性能的索引。

您可以通过调用 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
const result = await movies.createIndex({ cast: 1 });

以下代码查询多键索引以查找 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);

多键索引在查询覆盖、索引边界计算和排序行为方面与非多键索引的行为不同。有关多键索引的完整解释,包括其行为和限制的讨论,请参阅 MongoDB 服务器手册中的 多键索引页面

聚集索引是提高对聚集集合的插入、更新和删除操作性能的索引。聚集集合按聚集索引键值存储文档。

要创建聚集索引,请在CollectionOption中指定clusteredIndex选项。必须指定clusteredIndex选项,将_id字段作为键,并将唯一字段指定为true

以下示例使用createCollection()方法在tea数据库的vendors集合中的_id字段上创建聚集索引。

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

有关更多信息,请参阅聚集索引聚集集合

文本索引支持对字符串内容的文本搜索查询。这些索引可以包括任何值是字符串或字符串元素数组的字段。

MongoDB支持多种语言的文本搜索,因此您可以在创建索引时指定默认语言作为选项。您还可以指定权重选项,以在索引中优先考虑某些文本字段。这些权重表示字段相对于其他索引字段的相对重要性。

有关文本搜索的更多信息,请参阅我们关于文本搜索查询.

以下示例使用createIndex()方法执行以下操作

  • blogPosts集合中的titlebody字段上创建text索引

  • 指定english作为默认语言

  • body字段的权重设置为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 } }
);

以下查询使用前面代码中创建的文本索引

// 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);

有关文本索引的更多信息,请参阅服务器手册中的文本索引

MongoDB 支持使用 2dsphere 索引 对地理空间坐标数据进行查询。使用 2dsphere 索引,您可以查询包含、相交和邻近的地理空间数据。有关使用 MongoDB Node.js 驱动程序查询地理空间数据的更多信息,请参阅我们的 搜索地理空间 指南。

要创建 2dsphere 索引,您必须指定仅包含 GeoJSON 对象 的字段。有关此类型的更多详细信息,请参阅 MongoDB 服务器手册页面上的 GeoJSON 对象

以下示例文档中 location.geo 字段来自 sample_mflix 数据库中 theaters 集合,是一个描述剧院坐标的 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
]
}
}
}

以下示例使用 createIndexes() 方法在 sample_mflix 数据库中 theaters 集合的 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 */
const result = await movies.createIndex({ "location.geo": "2dsphere" });
// Print the result of the index creation
console.log(`Index created: ${result}`);

MongoDB 还支持 2d 索引,用于在欧几里得平面上计算距离以及处理 MongoDB 2.2 及更早版本中使用的“传统坐标对”语法。有关更多信息,请参阅 地理空间查询

唯一索引 确保索引字段不存储重复值。默认情况下,MongoDB 在创建集合时会创建一个唯一索引在 _id 字段上。要创建唯一索引,指定您希望防止重复的字段或字段组合,并将 unique 选项设置为 true

以下示例使用 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.
const result = await movies.createIndex({ theaterId: 1 }, { unique: true });
console.log(`Index created: ${result}`);

如果您尝试执行写入操作并存储违反唯一索引的重复值,MongoDB 将抛出一个类似于以下错误

E11000 duplicate key error index

要了解更多信息,请参阅 唯一索引。

Atlas Search 是一种允许您执行全文搜索的功能。要了解更多信息,请参阅 Atlas Search 文档。

在您可以对 Atlas 集合执行搜索之前,您必须首先在集合上创建 Atlas Search 索引。Atlas Search 索引是一种将数据分类为可搜索格式的数据结构。

您可以使用以下方法来管理您的搜索索引

  • createSearchIndex()

  • createSearchIndexes()

  • listSearchIndexes()

  • updateSearchIndex()

  • dropSearchIndex()

以下各节提供了使用上述每个方法来管理搜索索引的代码示例。

您可以使用 createSearchIndex()createSearchIndexes() 方法来创建新的搜索索引。

以下代码演示了如何使用 createSearchIndex() 方法创建一个名为 search1 的索引。

// Create a search index
const index1 = {
name: "search1",
definition: {
"mappings": {
"dynamic": true
}
}
}
await collection.createSearchIndex(index1);

当连接到 MongoDB 服务器 v6.0.11 及更高版本,或 v7.0.2 及更高版本时,您可以使用驱动程序在集合上创建 Atlas 向量搜索索引。有关此功能的更多信息,请参阅Atlas 向量搜索文档。

以下代码演示了如何使用 createSearchIndex() 方法创建一个其中 type 字段为 vectorSearch 的搜索索引。

// Create a Vector Search index
const vectorSearchIdx = {
name: "vsidx1",
type: "vectorSearch",
definition: {
fields: [{
type: "vector",
numDimensions: 384,
path: "summary",
similarity: "dotProduct"
}]
}
}
await collection.createSearchIndex(vectorSearchIdx);

您可以使用 listSearchIndexes() 方法来返回一个包含给定集合的搜索索引的游标。listSearchIndexes() 方法接受一个可选的字符串参数 name,以返回只有匹配名称的索引。它还接受一个可选的 aggregateOptions 参数。

以下代码使用 listSearchIndexes() 方法列出集合中的搜索索引

// List search indexes
const result = await collection.listSearchIndexes().toArray();
console.log("Existing search indexes:\n");
for (const doc in result) {
console.log(doc);
}

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

以下代码展示了如何使用updateSearchIndex()方法来更新名为search1的索引,以指定字符串类型给description字段

// Update a search index
const index2 = {
"mappings": {
"dynamic": true,
"fields": {
"description": {
"type": "string"
}
}
}
}
await collection.updateSearchIndex("search1", index2);

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

以下代码展示了如何使用dropSearchIndex()方法来删除名为search1的索引

// Dropping (deleting) a search index
await collection.dropSearchIndex("search1");

返回

运行命令