db.collection.getindexes() 可获取集合所有索引定义,但无法反映字段类型、空值分布及实际查询命中情况,需结合 explain、countdocuments 等命令验证;执行前须确认数据库上下文、集合名大小写及用户权限;返回结果中 key、partialfilterexpression、unique、sparse 和 _id 字段最关键;批量查索引应优先使用驱动原生方法而非 getcollectionnames() 配 foreach。

db.collection.getIndexes() 就能拿到当前集合所有索引的完整定义,包括隐藏索引和正在构建中的索引。但它不告诉你字段类型、是否嵌套、有没有空值,也不能反映索引实际是否被查询命中——这些得靠组合命令验证。
执行 db.collection.getIndexes() 前必须确认三件事
这个命令看着简单,但失败常因环境配置而非语法错误:
- 先
use yourDB切换到目标数据库,否则会报ReferenceError: collection is not defined - 集合名大小写敏感,
db.users.getIndexes()和db.Users.getIndexes()是两个不同操作 - 用户权限不足时会返回
OperationFailure: not authorized on ... listIndexes,需确保角色含read或显式授予listIndexes权限
getIndexes() 返回结果里哪些字段最关键
返回的是数组,每项是一个索引文档。别只扫一眼 name,重点看这几个字段:
-
key:决定索引字段和方向,{"status": 1, "createdAt": -1}表示 status 升序 + createdAt 降序;{"email": "hashed"}或{"content": "text"}直接标明索引类型 -
partialFilterExpression存在说明是部分索引,比如{"status": "active"},那只有查{status: "active"}才可能用上它 -
unique和sparse为true时会影响写入逻辑和空值行为,别忽略 -
_id_索引永远存在且不可删,它一定会出现在返回数组里
想批量查一个库所有集合的索引?别用 getCollectionNames() 配 forEach
这种写法在 mongosh 里能跑,但在自动化脚本或生产环境里风险高:
-
db.getCollectionNames()在大库中可能超时或阻塞,尤其当集合数 > 1000 - 遇到系统集合(如
system.views)或权限受限集合时会中断整个循环 - 更稳妥的做法是用驱动原生方法:
PyMongo 中用collection.list_indexes()(返回CommandCursor,记得list(...)转成列表)
Node.js 中用collection.indexes()(返回 Promise,必须await) - 两者都支持
filter参数,比如{key: {"score": 1}}可筛出含 score 字段的索引,注意key是 BSON 文档,不是字符串匹配
光看 getIndexes() 输出还不够,必须验证索引是否真被用上
索引存在 ≠ 查询会走它。常见误判场景:
- 查询带
$or、$ne、$regex(非前缀)时,即使有对应字段索引也可能退化为全表扫描 - 排序字段没包含在索引 key 里,或者顺序不匹配,会导致
IXSCAN后接SORT,性能断崖下跌 - 投影字段过多(尤其是含
$操作符)会让索引无法覆盖,触发COLLSCAN - 验证方法:用
db.collection.find({}).explain("executionStats"),重点看executionStages.stage是IXSCAN还是COLLSCAN,以及totalDocsExamined是否接近nReturned
{"userId": 1} 的索引,如果 95% 文档 userId 为空或重复值极低,它的实际效果可能远不如预期。这时候 findOne() 看样例 + countDocuments({userId: {$exists: true}}) 统计非空比例,比死盯 getIndexes() 输出有用得多。











