MongoDB索引创建Skill mongodb-index-creation

这个技能教授如何创建和管理 MongoDB 索引,包括单字段、复合、唯一、文本、地理空间和 TTL 索引,以优化查询性能,提升数据库效率。关键词:MongoDB, 索引, 查询优化, 数据库性能, 索引管理, 后端开发, 数据存储。

后端开发 0 次安装 0 次浏览 更新于 3/14/2026

name: mongodb-index-creation version: “2.1.0” description: 掌握 MongoDB 索引创建和类型。学习单字段、复合、唯一、文本、地理空间和 TTL 索引。通过正确的索引显著优化查询性能。 sasmp_version: “1.3.0” bonded_agent: 04-mongodb-performance-indexing bond_type: PRIMARY_BOND

生产级技能配置

capabilities:

  • 单字段索引
  • 复合索引
  • 唯一索引
  • 文本索引
  • 地理空间索引
  • ttl索引

input_validation: required_context: - 集合名称 - 查询模式 optional_context: - 现有索引 - 写入频率 - 集合大小

output_format: index_definition: object creation_command: string impact_analysis: object maintenance_notes: array

error_handling: common_errors: - code: INDEX001 condition: “重复索引” recovery: “检查现有索引,创建前删除重复” - code: INDEX002 condition: “后台索引构建失败” recovery: “检查磁盘空间、内存,使用 background: true 重新构建” - code: INDEX003 condition: “索引过大,内存不足” recovery: “考虑部分索引或移除低价值索引”

prerequisites: mongodb_version: “4.4+” required_knowledge: - 查询模式 - esr-规则 performance_baseline: - “当前查询延迟已记录”

testing: unit_test_template: | // 验证索引创建和使用 await collection.createIndex({ field: 1 }) const indexes = await collection.indexes() expect(indexes.some(i => i.key.field === 1)).toBe(true) const explain = await collection.find({ field: value }).explain() expect(explain.queryPlanner.winningPlan.inputStage.stage).toBe(‘IXSCAN’)

MongoDB 索引创建与类型

通过策略性索引显著提升查询性能。

快速开始

创建索引

// 单字段索引
await collection.createIndex({ email: 1 })

// 复合索引(顺序很重要!)
await collection.createIndex({ status: 1, createdAt: -1 })

// 唯一索引
await collection.createIndex({ email: 1 }, { unique: true })

// 稀疏索引(跳过空值)
await collection.createIndex({ phone: 1 }, { sparse: true })

// TTL 索引(24小时后自动删除)
await collection.createIndex({ createdAt: 1 }, { expireAfterSeconds: 86400 })

// 文本索引(全文搜索)
await collection.createIndex({ title: 'text', content: 'text' })

// 地理空间索引
await collection.createIndex({ location: '2dsphere' })

索引类型

单字段索引

// 一个字段的简单索引
db.users.createIndex({ email: 1 })

// 好处:
// - 加速基于 email 字段的查询
// - 加速基于 email 的排序
// - 加速范围查询:{ $gt, $lt }

// 使用时机:
// - 频繁过滤或排序的字段
// - 高基数(许多唯一值)

复合索引

// 多个字段 - 顺序很重要!
db.orders.createIndex({ status: 1, createdAt: -1 })

// 适用于查询如:
// { status: 'completed', createdAt: {$gt: date} }
// { status: 'completed' } // 可以使用此索引

// 不适用于:
// { createdAt: {$gt: date} } // 索引效果不佳

唯一索引

// 确保字段唯一性
db.users.createIndex({ email: 1 }, { unique: true })

// 防止重复:
// - insertOne 带重复 email → 错误
// - 如果 email 已存在,无法插入

// 稀疏唯一(允许多个空值)
db.users.createIndex({ phone: 1 }, { unique: true, sparse: true })

稀疏索引

// 跳过字段为空或缺失的文档
db.users.createIndex({ phone: 1 }, { sparse: true })

// 好处:
// - 索引更小(排除空值)
// - 匹配查询 { $exists: true }

// 使用时机:
// - 可选字段(非所有文档都有)
// - 减少索引大小

文本索引

// 全文搜索
db.articles.createIndex({
  title: 'text',
  content: 'text',
  tags: 'text'
})

// 查询:
db.articles.find({ $text: { $search: 'mongodb' } })

// 权重(title 比 content 更重要)
db.articles.createIndex({
  title: 'text',
  content: 'text'
}, { weights: { title: 10, content: 5 } })

地理空间索引

// 2D 球面(经纬度)
db.venues.createIndex({ location: '2dsphere' })

// 查询附近
db.venues.find({
  location: {
    $near: {
      type: 'Point',
      coordinates: [-73.97, 40.77]
    },
    $maxDistance: 5000  // 5公里
  }
})

TTL 索引

// 一段时间后自动删除文档
db.sessions.createIndex({ createdAt: 1 }, {
  expireAfterSeconds: 3600  // 1小时
})

// 使用案例:
// - 会话过期
// - 临时日志
// - 缓存类集合

// MongoDB 每分钟检查一次
// 删除可能延迟最多 1 分钟

索引管理

列出索引

// 显示所有索引
const indexes = await collection.indexes()
console.log(indexes)

// 显示:名称、键、大小、文档计数

删除索引

// 删除特定索引
await collection.dropIndex('email_1')

// 删除所有非 _id 索引
await collection.dropIndexes()

索引选项

await collection.createIndex({ email: 1 }, {
  unique: true,           // 强制唯一性
  sparse: true,          // 跳过空值
  background: true,      // 不阻塞写入
  expireAfterSeconds: 86400, // TTL
  collation: { locale: 'en' }, // 语言特定
  name: 'custom_name'    // 自定义索引名称
})

索引设计:ESR 规则

相等、排序、范围 - 最佳复合索引顺序

// 查询:查找活跃用户,按创建日期排序,年龄 18-65
db.users.find({
  status: 'active',          // 相等
  age: { $gte: 18, $lte: 65 } // 范围
}).sort({ createdAt: -1 })     // 排序

// 最佳索引:
db.users.createIndex({
  status: 1,         // 相等优先
  createdAt: -1,    // 排序第二
  age: 1            // 范围最后
})

覆盖查询

使查询“覆盖”

// 查询完全从索引返回,无需获取文档!

// 创建包含所有所需字段的索引
db.users.createIndex({ email: 1, name: 1, age: 1 })

// 查询(覆盖 - 无文档获取)
db.users.find(
  { email: 'user@example.com' },
  { projection: { email: 1, name: 1, age: 1, _id: 0 } }
)

// 比获取文档快得多!

监控索引

检查索引使用情况

// MongoDB 4.4+
db.collection.aggregate([
  { $indexStats: {} }
])

// 显示:
// - accesses.ops:使用索引的操作次数
// - accesses.since:索引创建时间

移除未使用索引

// 识别未使用:
// - accesses.ops 值低
// - accesses.since 日期较近

// 删除未使用索引:
await collection.dropIndex('unused_index_name')

最佳实践

索引设计:

  1. 为查询索引 - 在频繁过滤的字段上添加索引
  2. 使用 ESR 规则 - 相等、排序、范围的顺序
  3. 避免过度索引 - 每个索引都有成本
  4. 监控索引大小 - 大索引需要内存
  5. 测试影响 - 测量查询性能

性能:

  1. 尽早创建索引 - 在数据增长之前
  2. 使用 explain() - 验证索引使用(IXSCAN)
  3. 批量索引创建 - 如果需要多个
  4. 监控索引统计 - 移除未使用
  5. 规划增长 - 未来查询模式

避免:

  1. 索引所有内容 - 浪费存储和内存
  2. 无索引的复杂正则表达式 - 总是慢
  3. 无索引排序 - 内存密集
  4. 大型文本索引 - 内存使用
  5. 过时索引 - 不再需要时移除

下一步

  1. 识别慢查询 - 使用 explain()
  2. 创建策略性索引 - 针对您的访问模式
  3. 监控性能 - 前后指标
  4. 优化复合索引 - ESR 规则
  5. 移除未使用索引 - 保持精简

准备加速您的 MongoDB!