在 MongoDB 中,sparse
是创建索引时的一个重要选项,当设置为 true
时,会创建稀疏索引(Sparse Index)。它的核心特性是:只对包含索引字段的文档建立索引条目,不包含该字段的文档会被自动排除在索引之外。这与默认的非稀疏索引(对所有文档建立索引,即使字段不存在时也会存储 null
或缺失标记)形成鲜明对比。
稀疏索引(sparse: true)的核心特点
仅索引包含目标字段的文档
对于不包含索引字段的文档,稀疏索引不会为其创建任何索引条目,无论该字段是缺失还是值为null
(注意:若字段存在但值为null
,默认仍会被索引,除非结合sparse
和其他过滤条件)。减少索引体积
由于跳过了不含索引字段的文档,稀疏索引的存储空间通常比非稀疏索引更小,查询时的扫描范围也可能更小,性能更优。不影响文档写入
稀疏索引仅影响索引的构建和查询,不限制文档的插入 / 更新(即使文档不含索引字段,也能正常写入)。
使用场景
稀疏索引适合以下场景:
- 字段在部分文档中存在:例如,一个
users
集合中,只有部分用户有email
字段(如企业用户),对email
创建稀疏索引可避免为无邮箱的用户浪费索引空间。 - 优化查询优化:当查询条件仅针对包含该字段的文档时,稀疏索引能快速定位目标文档,减少无效扫描。
示例演示
假设 users
集合有以下文档:
// 文档1:包含 email 字段
{ _id: 1, name: "Alice", email: "alice@example.com" }
// 文档2:包含 email 字段(值为 null)
{ _id: 2, name: "Bob", email: null }
// 文档3:不包含 email 字段
{ _id: 3, name: "Charlie" }
1. 创建稀疏索引
// 对 email 字段创建稀疏索引
db.users.users.createIndex({ email: 1 }, { sparse: true })
2. 索引包含的条目
稀疏索引仅包含文档 1 和文档 2(因为它们有 email
字段,即使值为 null
),文档 3 会被排除(无 email
字段)。
3. 查询行为
- 当查询条件为
{ email: { $exists: true } }
时,稀疏索引会被命中优化,快速效率更高。 - 当查询条件为
{ email: null }
时,会返回文档 2(因为它被索引包含)。 - 当查询条件为
{ email: { $exists: false } }
时,稀疏索引不会被使用(因为这些文档不在索引中),MongoDB 会执行全表扫描。
与非稀疏索引的对比
特性 | 稀疏索引(sparse: true) | 非稀疏索引(默认) |
---|---|---|
索引条目范围 | 仅包含有索引字段的文档 | 包含所有文档(无字段时记为 null ) |
索引体积 | 较小(跳过无字段文档) | 较大(包含所有文档) |
适用场景 | 字段存在于部分文档,且需按该字段查询 | 字段普遍存在,或需查询 “无此字段” 的文档 |
查询 “无字段” 文档 | 无法使用索引(需全表扫描) | 可使用索引(通过 null 匹配) |
注意事项
与唯一索引结合时的限制
若稀疏索引同时设置为唯一索引(unique: true
),则:- 允许多个文档不包含该字段(因为它们不进入索引,不会冲突)。
- 但包含该字段的文档必须有唯一值(否则违反唯一性约束)。
示例:
// 唯一稀疏索引:允许多个文档无 email,但有 email 的文档必须唯一 db.users.createIndex({ email: 1 }, { sparse: true, unique: true })
地理空间索引的特殊性
地理空间索引(如2d
、2dsphere
)默认是稀疏的,即使不指定sparse: true
,也只会索引包含有效地理字段的文档。查询时的索引使用限制
当查询条件可能匹配 “不含索引字段的文档” 时,MongoDB 可能不会使用稀疏索引,需通过explain()
验证索引是否被命中。与部分索引(Partial Index)的区别
稀疏索引是部分索引的一种特殊情况(仅基于 “字段是否存在” 过滤文档),而部分索引可通过filter
条件更灵活地筛选需索引的文档(如{ age: { $gt: 18 } }
)。
总结
sparse: true
选项用于创建稀疏索引,其核心价值是只索引包含目标字段的文档,从而减少索引体积并优化特定查询。适合字段存在于部分文档且需按该字段查询的场景,但需注意其在查询 “无字段文档” 时的局限性,以及与唯一索引结合时的特殊行为。实际使用中,可结合 explain()
分析索引效果,或考虑更灵活的部分索引(Partial Index)满足复杂需求。