管理索引

    • Mongo Shell

    在本页面

    此页显示如何管理现有索引。有关创建索引的说明,请参阅特定索引类型页。

    查看现有索引

    以下部分提供了查看集合或整个数据库上现有索引的方法。

    列出集合上的所有索引

    要返回一个集合上所有索引的列表,使用db. collections . getindexes ()方法或类似的驱动程序的方法

    例如,要查看people集合上的所有索引,运行以下命令:

    1. db.people.getIndexes()

    列出数据库的所有索引

    mongo shell中,可以使用以下操作列出数据库中所有的集合索引:

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

    从3.0版本开始,MongoDB不再支持对系统的直接访问。索引集合,以前用于列出数据库中的所有索引。

    列出特定类型的索引

    列出所有索引的类型(例如散列,文本)集合在所有数据库,您可以使用以下操作在mongoshell:

    1. // The following finds all hashed indexes
    2. db.adminCommand("listDatabases").databases.forEach(function(d){
    3. let mdb = db.getSiblingDB(d.name);
    4. mdb.getCollectionInfos({ type: "collection" }).forEach(function(c){
    5. let currentCollection = mdb.getCollection(c.name);
    6. currentCollection.getIndexes().forEach(function(idx){
    7. let idxValues = Object.values(Object.assign({}, idx.key));
    8. if (idxValues.includes("hashed")) {
    9. print("Hashed index: " + idx.name + " on " + idx.ns);
    10. printjson(idx);
    11. };
    12. });
    13. });
    14. });

    删除索引

    MongoDB提供了两种方法从集合中删除索引:

    要删除一个索引,使用db.collection.dropIndex()方法。

    例如,下面的操作删除了 accounts 集合中的 tax-id 字段的升序索引:

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

    该操作返回一个文档,其中显示了该操作的状态:

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

    其中nIndexesWas的值反映了在删除这个索引之前的索引数量。

    对于文本索引,将索引名称传递给 db.collection.dropIndex()方法。有关详细信息,请参见使用索引名称删除文本索引

    注意

    从MongoDB 4.2开始,‘ db.collection.dropIndexes() ‘可以接受一个索引名称数组。

    删除所有索引

    你也可以使用db. collections . dropindexes ()从一个集合中删除_id索引之外的所有索引。

    例如,下面的命令从 accounts 集合中删除所有索引:

    1. db.accounts.dropIndexes()

    这些shell助手提供了dropIndexes 数据库命令的包装器。您的客户端库可能有一个不同的或额外的接口用于这些操作。

    修改索引

    要修改现有索引,您需要删除并重新创建索引。TTL索引是该规则的例外 ,可以通过collMod命令与index收集标志一起 对其进行修改。

    在分片中查找不一致的索引

    如果分片集合在每个包含该分片块的分片上没有完全相同的索引(包括索引选项),则该集合具有不一致的索引。虽然在正常操作中不应该出现索引不一致的情况,但也会出现索引不一致的情况,例如:

    • 当用户创建具有unique键约束的索引并且一个分片包含具有重复文档的块时。在这种情况下,创建索引操作可能会在没有重复的分片上成功,但在没有重复的分片上不会成功。
    • 当用户创建一个索引碎片在对面(滚动的方式(即手动构建跨多个碎片索引一个接一个地)但是无论未能构建相关碎片或是不正确的索引构建索引与不同的规范。

    从MongoDB 4.2.6,配置服务器主,默认情况下,检查索引不一致在分片的碎片集合,和命令(“serverStatus”),主要配置服务器上运行时,返回字段shardedIndexConsistency来报告索引不一致的分片集合的数量。

    如果shardedIndexConsistency报告任何索引不一致,则可以对分片集合运行以下管道,直到找到不一致为止。

    注意

    下面的管道用于MongoDB 4.2.4及以上版本。

    1. 定义以下聚合管道:

      1. const pipeline = [
      2. // Get indexes and the shards that they belong to.
      3. {$indexStats: {}},
      4. // Attach a list of all shards which reported indexes to each document from $indexStats.
      5. {$group: {_id: null, indexDoc: {$push: "$$ROOT"}, allShards: {$addToSet: "$shard"}}},
      6. // Unwind the generated array back into an array of index documents.
      7. {$unwind: "$indexDoc"},
      8. // Group by index name.
      9. {
      10. $group: {
      11. "_id": "$indexDoc.name",
      12. "shards": {$push: "$indexDoc.shard"},
      13. // Convert each index specification into an array of its properties
      14. // that can be compared using set operators.
      15. "specs": {$push: {$objectToArray: {$ifNull: ["$indexDoc.spec", {}]}}},
      16. "allShards": {$first: "$allShards"}
      17. }
      18. },
      19. // Compute which indexes are not present on all targeted shards and
      20. // which index specification properties aren't the same across all shards.
      21. {
      22. $project: {
      23. missingFromShards: {$setDifference: ["$allShards", "$shards"]},
      24. inconsistentProperties: {
      25. $setDifference: [
      26. {$reduce: {
      27. input: "$specs",
      28. initialValue: {$arrayElemAt: ["$specs", 0]},
      29. in: {$setUnion: ["$$value", "$$this"]}}},
      30. {$reduce: {
      31. input: "$specs",
      32. initialValue: {$arrayElemAt: ["$specs", 0]},
      33. in: {$setIntersection: ["$$value", "$$this"]}}}
      34. ]
      35. }
      36. }
      37. },
      38. // Only return output that indicates an index was inconsistent, i.e. either a shard was missing
      39. // an index or a property on at least one shard was not the same on all others.
      40. {
      41. $match: {
      42. $expr:
      43. {$or: [
      44. {$gt: [{$size: "$missingFromShards"}, 0]},
      45. {$gt: [{$size: "$inconsistentProperties"}, 0]},
      46. ]
      47. }
      48. }
      49. },
      50. // Output relevant fields.
      51. {$project: {_id: 0, indexName: "$$ROOT._id", inconsistentProperties: 1, missingFromShards: 1}}
      52. ];
    2. 运行要测试的分片集合的聚合管道。例如,要测试分片集合是否测试。在相关的碎片上有不一致的索引:

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

      如果集合的索引不一致,则该集合的聚合将返回关于不一致索引的详细信息:

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

    返回的文档指出了分片集合 test.reviews 的两个不一致之处:

    1. shardB上的集合中缺少一个名为page_1_score_1的索引。
      1. 一个名为reviewDt_1的索引在集合的各个分片上具有不一致的属性,特别是expireAfterSeconds属性不同。

    要解决特定分片集合中缺少索引的不一致问题

    ​ 从受影响的分片上的集合中删除不正确的索引,然后重建索引。要重建索引,您可以:

    要解决索引属性在各个分片之间的差异

    ​ 从受影响的分片上的集合中删除不正确的索引,并重新构建索引。重建索引,你可以:

    或者,如果不一致是该expireAfterSeconds属性,则可以运行collMod命令以更新秒数,而不是删除并重建索引。