db.collection.getindexes() 返回索引完整定义数组,含key、name等字段,但不显示字段类型或嵌套结构;需结合findone()和explain()验证实际使用效果,并注意权限、大小写及系统集合覆盖问题。

直接看 db.collection.getIndexes() 就能拿到所有索引的完整定义,但仅靠它看不到字段类型、嵌套结构或文档样例——这些得靠组合命令手动探查。
用 getIndexes() 查索引详情,别只看返回数组
这个方法返回的是一个数组,每项是完整索引文档,包含 key、name、unique、sparse、partialFilterExpression 等关键字段。容易忽略的是:key 字段里值为 1 表示升序,-1 是降序,"hashed" 或 "text" 会直接写出来;partialFilterExpression 如果存在,说明这是个部分索引,它的条件必须和查询谓词匹配才可能被选中。
- 执行前先
use yourDB,再db.yourCollection.getIndexes() - 如果返回空数组,不代表没索引——可能是权限不足,或集合名拼错(MongoDB 对大小写敏感)
-
_id索引永远存在且不可删,它不会出现在getIndexes()返回里吗?会,但名字固定为"_id_"
用 findOne() + explain("executionStats") 推断字段结构
索引定义不告诉你字段是否存在、是否常为空、是否嵌套。最实打实的办法是取一条真实文档看结构,再结合查询计划验证索引是否真被用上。
-
db.yourCollection.findOne()能看到任意一个文档的字段和值类型(比如"score": 92是 number,"notes": "..."是 string) - 加
.explain("executionStats"):如db.yourCollection.find({score: {$gt: 80}}).explain("executionStats"),重点看executionStages.stage是"IXSCAN"还是"COLLSCAN",以及nReturned和totalDocsExamined是否接近 - 如果
totalDocsExamined远大于nReturned,说明索引没覆盖查询,或者排序/投影导致无法使用索引
用 list_indexes()(PyMongo)或 indexes()(Node.js)替代 shell 命令
生产环境脚本里别硬编码 mongo shell 命令,驱动原生方法更可控、可错误捕获。
- PyMongo 中用
collection.list_indexes(),返回的是CommandCursor,需转成 list 才能遍历:list(collection.list_indexes()) - Node.js 驱动里对应的是
collection.indexes(),返回 Promise,注意 await 后才是数组 - 两者都支持传 filter 参数,例如
{key: {"score": 1}}可筛选出含score字段的索引,但注意 key 是 BSON 文档,不是字符串匹配 - 如果遇到
OperationFailure: not authorized on ...,不是代码问题,是数据库用户没授予listIndexes权限
批量查所有集合的索引时,避开 getCollectionNames() 的坑
在 mongosh 里想扫整个库的索引,别直接循环 getCollectionNames() —— 它不返回系统集合(如 system.views),而且某些隐藏集合会被跳过。
- 更稳的方式是用
db.getCollectionInfos({type: "collection"}),它返回所有用户集合的元信息,包括name和options - 对每个
info.name调用db[info.name].getIndexes(),比db[info.name].getIndexes()更安全,避免集合名含特殊字符时报错 - 如果某集合返回
undefined或空数组,先确认它是否真有数据:db.info.name.countDocuments({}),空集合可能还没建索引
索引信息本身是静态快照,但它的有效性取决于查询模式、数据分布和 MongoDB 版本特性(比如 8.0+ 的查询设置会覆盖旧的索引筛选器逻辑)。别只盯着 getIndexes() 输出就下结论,一定结合实际查询的 explain 结果交叉验证。











