Database Manual / Indexes

Manage Indexes管理索引

This page shows how to manage existing indexes. For instructions on creating indexes, refer to the specific index type pages.此页面显示如何管理现有索引。有关创建索引的说明,请参阅特定的索引类型页面。

View Existing Indexes查看现有索引

MongoDB Shell

The following sections provide methods for viewing existing indexes on a collection or an entire database.以下部分提供了查看集合或整个数据库上现有索引的方法。

List All Indexes on a Collection列出集合上的所有索引

To return a list of all indexes on a collection, use the db.collection.getIndexes() method or a similar method for your driver.要返回集合上所有索引的列表,请使用db.collection.getIndexes()方法或驱动程序的类似方法

For example, to view all indexes on the people collection, run the following command:例如,要查看people集合上的所有索引,请运行以下命令:

db.people.getIndexes()

List All Indexes for a Database列出数据库的所有索引

To list all the collection indexes in a database, run the following command in mongosh:要列出数据库中的所有集合索引,请在mongosh中运行以下命令:

db.getCollectionNames().forEach(function(collection) {
indexes = db[collection].getIndexes();
print("Indexes for " + collection + ":");
printjson(indexes);
});

List Specific Type of Indexes列出特定类型的索引

To list all indexes of a certain type (such as hashed or text) for all collections in all database, run the following command in mongosh:要列出所有数据库中所有集合的特定类型(如哈希文本)的所有索引,请在mongosh中运行以下命令:

// The following finds all hashed indexes下面查找所有哈希索引

db.adminCommand("listDatabases").databases.forEach(function(d){
let mdb = db.getSiblingDB(d.name);
mdb.getCollectionInfos({ type: "collection" }).forEach(function(c){
let currentCollection = mdb.getCollection(c.name);
currentCollection.getIndexes().forEach(function(idx){
let idxValues = Object.values(Object.assign({}, idx.key));

if (idxValues.includes("hashed")) {
print("Hashed index: " + idx.name + " on " + d.name + "." + c.name);
printjson(idx);
};
});
});
});
Compass

To view a list of all indexes on a collection in MongoDB Compass, click on the target collection in the left-hand pane and select the Indexes tab.要查看MongoDB Compass中集合上所有索引的列表,请单击左侧窗格中的目标集合,然后选择“索引”选项卡。

View indexes on a collection in Compass

For details on the information displayed in this tab, refer to the Compass documentation.有关此选项卡中显示的信息的详细信息,请参阅Compass文档

Remove Indexes删除索引

Tip

Hide an Index Before Dropping It在删除索引之前隐藏它

If you drop an index that is actively used in production, your application may incur a performance degradation. Before you drop an index, you can evaluate the potential impact of the drop by hiding the index.如果您删除了生产中正在使用的索引,应用程序可能会导致性能下降。在删除索引之前,可以通过隐藏索引来评估删除的潜在影响。

Hidden indexes are not used to support queries. If you hide an index and observe substantial negative performance impact, consider keeping and unhiding the index so queries can resume using it.隐藏索引不用于支持查询。如果隐藏索引并观察到对性能有重大负面影响,请考虑保留和取消隐藏索引,以便查询可以继续使用它。

To learn how to remove an existing index, see Drop an Index.要了解如何删除现有索引,请参阅删除索引

To learn how to remove an index in MongoDB Compass, see Manage Indexes in Compass.要了解如何在MongoDB Compass中删除索引,请参阅Compass中的管理索引

Modify an Index修改索引

MongoDB Shell

To modify an existing index in the MongoDB Shell, you need to drop and recreate the index. 要修改MongoDB Shell中的现有索引,您需要删除并重新创建索引。The exception to this rule is TTL indexes, which can be modified via the collMod command in conjunction with the index collection flag.此规则的例外是TTL索引,可以通过collMod命令结合index集合标志进行修改。

Compass

To modify an existing index in MongoDB Compass, you need to drop and recreate the index.要修改MongoDB Compass中的现有索引,您需要删除并重新创建索引。

Minimize Performance Impact With a Temporary Index使用临时索引将性能影响降至最低

If you drop an index that is actively used in production, your application may incur a performance degradation. To ensure queries can still use an index during modification, you can create a temporary, redundant index that contains the same fields as the modified index.如果您删除了生产中正在使用的索引,应用程序可能会导致性能下降。为了确保查询在修改过程中仍然可以使用索引,您可以创建一个临时的冗余索引,其中包含与修改后的索引相同的字段。

Example示例

This example creates a new index and modifies that index to make it unique.此示例创建一个新索引并修改该索引使其唯一

1
Create a siteAnalytics collection with an index on the url fieldurl字段上创建带有索引的siteAnalytics集合

Run this command:运行此命令:

db.siteAnalytics.createIndex( { "url": 1 } )

The command returns the name of the index:该命令返回索引的名称:

url_1
2
Create a temporary index that contains the url field创建一个包含url字段的临时索引

Run this command:运行此命令:

db.siteAnalytics.createIndex( { "url": 1, "dummyField": 1 } )

The command returns the name of the index:该命令返回索引的名称:

url_1_dummyField_1

This temporary index lets you safely drop the original { "url": 1 } index without impacting performance.此临时索引允许您安全地删除原始的{ "url": 1 }索引,而不会影响性能。

3
Drop the original index删除原始索引

Run this command:运行此命令:

db.siteAnalytics.dropIndex( { "url_1" } )

The command returns:命令返回:

{ nIndexesWas: 3, ok: 1 }
4
Recreate the { "url": 1 } index with the unique property使用unique属性重新创建{ "url": 1 }索引

Run this command:运行此命令:

db.siteAnalytics.createIndex( { "url": 1 }, { "unique": true } )

The command returns the name of the index:该命令返回索引的名称:

url_1

The url_1 index is recreated and you can drop the temporary index without impacting performance. Queries on the url field can use the new unique index.url_1索引已重新创建,您可以在不影响性能的情况下删除临时索引。对url字段的查询可以使用新的唯一索引。

5
Drop the temporary index删除临时索引

Run this command:运行此命令:

db.siteAnalytics.dropIndex( { "url_1_dummyField_1" } )

The command returns:命令返回:

{ nIndexesWas: 3, ok: 1 }
6
Confirm that the index was updated确认索引已更新

To view the indexes on the siteAnalytics collection, run this command:要查看siteAnalytics集合上的索引,请运行以下命令:

db.siteAnalytics.getIndexes()

The command returns these indexes, indicating that the url_1 index is now unique:该命令返回这些索引,表示url_1索引现在是唯一的:

[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{ v: 2, key: { url: 1 }, name: 'url_1', unique: true }
]

Find Inconsistent Indexes Across Shards查找分片间不一致的索引

A sharded collection has an inconsistent index if the collection does not have the exact same indexes (including the index options) on each shard that contains chunks for the collection. Although inconsistent indexes should not occur during normal operations, inconsistent indexes can occur , such as:如果一个分片集合在包含该集合块的每个分片上没有完全相同的索引(包括索引选项),则该分片集合的索引不一致。虽然在正常操作过程中不应出现不一致的索引,但可能会出现不一致索引,例如:

  • When a user is creating an index with a unique key constraint and one shard contains a chunk with duplicate documents. In such cases, the create index operation may succeed on the shards without duplicates but not on the shard with duplicates.当用户创建具有unique键约束的索引时,一个分片包含一个包含重复文档的块。在这种情况下,创建索引操作可能会在没有重复的分片上成功,但在有重复的分片上则不会成功。
  • When a user is creating an index across the shards in a rolling manner (i.e. manually building the index one by one across the shards) but either fails to build the index for an associated shard or incorrectly builds an index with different specification.当用户以滚动方式在分片之间创建索引时(即在分片上逐一手动构建索引),但要么无法为相关分片构建索引,要么错误地构建了具有不同规范的索引。

The config server primary, by default, checks for index inconsistencies across the shards for sharded collections, and the command serverStatus, when run on the config server primary, returns the field shardedIndexConsistency field to report on the number of sharded collections with index inconsistencies.默认情况下,配置服务器primary检查分片集合的分片索引不一致,在配置服务器primary上运行命令serverStatus时,返回字段shardedIndexConsistency字段,以报告索引不一致的分片集合数量。

If shardedIndexConsistency reports any index inconsistencies, you can run the following pipeline for your sharded collections until you find the inconsistencies.如果shardedIndexConsistency报告了任何索引不一致,您可以为分片集合运行以下管道,直到找到不一致为止。

  1. Define the following aggregation pipeline:定义以下聚合管道

    const pipeline = [
    // Get indexes and the shards that they belong to.获取索引及其所属的分片。
    {$indexStats: {}},
    // Attach a list of all shards which reported indexes to each document from $indexStats.$indexStats为每个文档附加一个所有报告索引的分片列表。
    {$group: {_id: null, indexDoc: {$push: "$$ROOT"}, allShards: {$addToSet: "$shard"}}},
    // Unwind the generated array back into an array of index documents.
    {$unwind: "$indexDoc"},
    // Group by index name.
    {
    $group: {
    "_id": "$indexDoc.name",
    "shards": {$push: "$indexDoc.shard"},
    // Convert each index specification into an array of its properties that can be compared using set operators.将每个索引规范转换为可以使用集合运算符进行比较的属性数组。
    "specs": {$push: {$objectToArray: {$ifNull: ["$indexDoc.spec", {}]}}},
    "allShards": {$first: "$allShards"}
    }
    },
    // Compute which indexes are not present on all targeted shards and which index specification properties aren't the same across all shards.计算哪些索引不存在于所有目标分片上,以及哪些索引规范属性在所有分片上不相同。
    {
    $project: {
    missingFromShards: {$setDifference: ["$allShards", "$shards"]},
    inconsistentProperties: {
    $setDifference: [
    {$reduce: {
    input: "$specs",
    initialValue: {$arrayElemAt: ["$specs", 0]},
    in: {$setUnion: ["$$value", "$$this"]}}},
    {$reduce: {
    input: "$specs",
    initialValue: {$arrayElemAt: ["$specs", 0]},
    in: {$setIntersection: ["$$value", "$$this"]}}}
    ]
    }
    }
    },
    // Only return output that indicates an index was inconsistent, i.e. either a shard was missing an index or a property on at least one shard was not the same on all others.仅返回指示索引不一致的输出,即某个分片缺少索引,或者至少一个分片上的属性在所有其他分片上都不相同。
    {
    $match: {
    $expr:
    {$or: [
    {$gt: [{$size: "$missingFromShards"}, 0]},
    {$gt: [{$size: "$inconsistentProperties"}, 0]},
    ]
    }
    }
    },
    // Output relevant fields.输出相关字段。
    {$project: {_id: 0, indexName: "$$ROOT._id", inconsistentProperties: 1, missingFromShards: 1}}
    ];
  2. Run the aggregation pipeline for the sharded collection to test. For example, to test if the sharded collection test.reviews has inconsistent indexes across its associated shards:运行分片集合的聚合管道进行测试。例如,为了测试分片集合test.reviews是否在其关联的分片之间具有不一致的索引:

    db.getSiblingDB("test").reviews.aggregate(pipeline)

    If the collection has inconsistent indexes, the aggregation for that collection returns details regarding the inconsistent indexes:如果集合的索引不一致,则该集合的聚合将返回有关不一致索引的详细信息:

    { "missingFromShards" : [ "shardB" ], "inconsistentProperties" : [ ], "indexName" : "page_1_score_1" }
    { "missingFromShards" : [ ], "inconsistentProperties" : [ { "k" : "expireAfterSeconds", "v" : 60 }, { "k" : "expireAfterSeconds", "v" : 600 } ], "indexName" : "reviewDt_1" }

    The returned documents indicate two inconsistencies for the sharded collection test.reviews:返回的文件表明分片集合test.reviews存在两个不一致之处:

    1. An index named page_1_score_1 is missing from the collection on shardB.shardB上的集合中缺少名为page_1_score_1的索引。
    2. An index named reviewDt_1 has inconsistent properties across the collection's shards, specifically, the expireAfterSeconds properties differ.名为reviewDt_1的索引在集合的分片中具有不一致的属性,具体来说,expireAfterSeconds属性不同。
To resolve the inconsistency where an index is missing from the collection on a particular shard(s),为了解决特定分片上的集合中缺少索引的不一致性,

You can either:您可以:

  • Issue an index build db.collection.createIndex() from a mongos instance. The operation only builds the collection's index on the shard(s) missing the index.mongos实例发出索引构建db.collection.createIndex()。该操作仅在缺少索引的分片上构建集合的索引。

    -OR-

  • Perform a rolling index build for the collection on the affected shard(s).对受影响的分片上的集合执行滚动索引构建

    Note

    Rolling indexes may negatively impact your deployment. For information on when to use this index build, see Rolling Index Builds.滚动索引可能会对部署产生负面影响。有关何时使用此索引构建的信息,请参阅滚动索引构建

Warning

Avoid performing rolling index and replicated index build processes concurrently as it might lead to unexpected issues, such as broken builds and crash loops.避免同时执行滚动索引和复制索引构建过程,因为这可能会导致意外问题,如构建中断和崩溃循环。

To resolve where the index properties differ across the shards,为了解决分片之间索引属性不同的地方,

Drop the incorrect index from the collection on the affected shard(s) and rebuild the index. To rebuild the index, you can either:从受影响分片的集合中删除不正确的索引,然后重建索引。要重建索引,您可以:

  • Issue an index build db.collection.createIndex() from a mongos instance. The operation only builds the collection's index on the shard(s) missing the index.mongos实例发出索引构建db.collection.createIndex()。该操作仅在缺少索引的分片上构建集合的索引。

    -OR-

  • Perform a rolling index build for the collection on the affected shard.对受影响的分片上的集合执行滚动索引构建

    Note

    Rolling indexes may negatively impact your deployment. For information on when to use this index build, see Rolling Index Builds.滚动索引可能会对部署产生负面影响。有关何时使用此索引构建的信息,请参阅滚动索引构建

Alternatively, if the inconsistency is the expireAfterSeconds property, you can run the collMod command to update the number of seconds instead of dropping and rebuilding the index.或者,如果不一致是expireAfterSeconds属性,则可以运行collMod命令来更新秒数,而不是删除和重建索引。