Manage Indexes管理索引

On this page本页内容

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

View Existing Indexes查看现有索引

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

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文档

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, you can use the following operation in the mongo shell:要列出数据库中的所有集合索引,可以在mongo shell中使用以下操作:

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

Starting in version 3.0, MongoDB deprecates direct access to the system.indexes collection, which had previously been used to list all indexes in a database.从3.0版开始,MongoDB不赞成直接访问system.indexes集合,该集合以前用于列出数据库中的所有索引。

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

To list all indexes of a certain type (e.g. hashed, text) for all collections in all database, you can use the following operation in the mongo shell:要列出所有数据库中所有集合的特定类型(如哈希text)的所有索引,可以在mongo shell中使用以下操作:

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

Remove Indexes删除索引

MongoDB provides two methods for removing indexes from a collection:MongoDB提供了两种从集合中删除索引的方法:

Remove Specific Index删除特定索引

To remove an index, use the db.collection.dropIndex() method.要删除索引,请使用db.collection.dropIndex()方法。

For example, the following operation removes an ascending index on the tax-id field in the accounts collection:例如,以下操作将删除accounts集合中tax-id字段的升序索引:

db.accounts.dropIndex( { "tax-id": 1 } )

The operation returns a document with the status of the operation:该操作返回一个带有操作状态的文档:

{ "nIndexesWas" : 3, "ok" : 1 }

Where the value of nIndexesWas reflects the number of indexes before removing this index.其中,nIndexesWas的值反映了删除此索引之前的索引数。

For text indexes, pass the index name to the db.collection.dropIndex() method. 对于text索引,将索引名传递给db.collection.dropIndex()方法。See Use the Index Name to Drop a text Index for details.有关详细信息,请参阅使用索引名删除文本索引

Note

Starting in MongoDB 4.2, db.collection.dropIndexes() can accept an array of index names.从MongoDB 4.2开始,db.collection.dropIndexes()可以接受一个索引名数组。

Starting in MongoDB 4.4, db.collection.dropIndexes() can stop in-progress index builds. 从MongoDB 4.4开始,db.collection.dropIndexes()可以停止正在进行的索引构建。See Aborts In-Progress Index Builds for more information.有关更多信息,请参阅中止进行中的索引生成

Remove All Indexes删除所有索引

You can also use the db.collection.dropIndexes() to remove all indexes except for the _id index from a collection.还可以使用db.collection.dropIndexes()从集合中删除除_id索引之外的所有索引。

For example, the following command removes all indexes from the accounts collection:例如,以下命令将从accounts集合中删除所有索引:

db.accounts.dropIndexes()

These shell helpers provide wrappers around the dropIndexes database command. 这些shell帮助程序围绕dropIndexes数据库命令提供包装。Your client library may have a different or additional interface for these operations.对于这些操作,客户端库可能有不同的或附加的接口。

To remove an index from a collection in MongoDB Compass:要从MongoDB Compass中的集合中删除索引,请执行以下操作:

  1. Navigate to the collection on which the target index exists.导航到目标索引所在的集合。
  2. Click the Indexes tab.单击“索引”选项卡。
  3. Click the trash can icon in the Drop column for the index you wish to delete.单击要删除的索引的“下拉”列中的“垃圾桶”图标。
Delete an index in Compass

Modify an Index修改索引

To modify an existing index, you need to drop and recreate the index. 要修改现有索引,需要删除并重新创建索引。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集合标志来修改。

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

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:虽然正常操作期间不应出现不一致的索引,但也可能出现不一致的索引,例如:

Starting in MongoDB 4.4 (and 4.2.6), 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.从MongoDB 4.4(和4.2.6)开始,默认情况下,配置服务器主服务器会检查切分集合的切分之间的索引不一致,而命令serverStatus在配置服务器主服务器上运行时,会返回字段shardedIndexConsistency字段,以报告索引不一致的切分集合的数量。

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

Note

The following pipeline is for MongoDB 4.2.4 and above.以下管道适用于MongoDB 4.2.4及以上版本。

  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:你可以:

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:要重建索引,可以执行以下操作之一:

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命令来更新秒数,而不是删除和重建索引。