MongoDB 高级索引
                           
天天向上
发布: 2025-03-09 09:32:19

原创
677 人浏览过

MongoDB 提供了强大的索引功能,以提高查询性能。除了基本的单字段索引和复合索引之外,MongoDB 还支持一系列高级索引类型,用于优化不同的查询场景。


1. 唯一索引(Unique Index)

唯一索引用于确保字段值的唯一性,类似于 SQL 的 UNIQUE 约束。

创建唯一索引

db.users.createIndex({ email: 1 }, { unique: true })

作用

  • 确保 email 字段的值在集合中是唯一的。
  • 如果插入重复值,MongoDB 将报错。

删除唯一索引

db.users.dropIndex("email_1")

2. 部分索引(Partial Index)

部分索引仅对符合特定条件的文档建立索引,减少索引大小,提高性能。

示例:仅索引 status 为 “active” 的用户

db.users.createIndex(
  { lastLogin: 1 },
  { partialFilterExpression: { status: "active" } }
)

作用

  • 仅对 status"active" 的文档创建索引,减少索引存储占用。
  • 提高查询效率,适用于查询某些特定类型的文档。

3. 稀疏索引(Sparse Index)

稀疏索引只索引包含指定字段的文档,未包含该字段的文档不会被索引,从而节省存储空间。

示例:创建 phone 字段的稀疏索引

db.users.createIndex({ phone: 1 }, { sparse: true })

作用

  • 仅对 phone 字段存在的文档建立索引,减少索引大小。
  • 查询 phone 的时候可以使用索引,但查询 phone: null 时不会走索引。

4. 复合索引(Compound Index)

复合索引用于多个字段的组合查询,优化复合条件查询的性能。

示例:创建 agecity 复合索引

db.users.createIndex({ age: 1, city: 1 })

作用

  • 可优化以下查询:
  db.users.find({ age: 30, city: "New York" })  // 使用索引
  db.users.find({ age: 30 })                    // 使用索引
  • 不会 优化:
  db.users.find({ city: "New York" })  // 不能单独使用 city 字段索引

索引前缀原则

  • db.users.find({ age: 30 }) 可以 使用索引(匹配索引的第一个字段)。
  • db.users.find({ city: "New York" }) 不会 使用索引(必须包含 age 才能使用)。
  • 索引字段的顺序很重要,如果查询经常用 city 作为首要查询条件,则应该创建 { city: 1, age: 1 }

5. 文字索引(Text Index)

MongoDB 提供全文索引,用于高效地进行文本搜索。

示例:创建全文索引

db.articles.createIndex({ content: "text" })

查询示例

db.articles.find({ $text: { $search: "MongoDB" } })

作用

  • 允许快速搜索包含 “MongoDB” 关键词的文档。
  • 适用于文章、博客等场景。

6. 哈希索引(Hashed Index)

哈希索引用于优化基于 _id 或随机字段的查询。

示例:创建哈希索引

db.users.createIndex({ userId: "hashed" })

作用

  • 适用于等值查询,如 db.users.find({ userId: "abc123" })
  • 不能用于范围查询($gt$lt 等)。

7. 地理空间索引(Geospatial Index)

MongoDB 支持 2dsphere2d 索引,用于处理地理坐标查询,如查找附近的商店、用户等

示例:创建 2dsphere 索引

db.places.createIndex({ location: "2dsphere" })

查询附近的位置

db.places.find({
  location: {
    $near: {
      $geometry: { type: "Point", coordinates: [40.7128, -74.0060] },
      $maxDistance: 5000  // 5公里范围内
    }
  }
})

作用

  • 适用于 GPS 位置查询,如查找附近的餐馆、ATM、商店等。

8. TTL(Time-To-Live)索引

TTL 索引用于自动删除过期数据,常见于日志、临时数据存储等。

示例:创建 TTL 索引

db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })

作用

  • 文档在 createdAt 字段创建 1 小时(3600 秒)后自动删除。
  • 适用于会话管理、缓存数据。

9. 覆盖索引(Covered Query)

如果一个查询的所有字段都在索引中,则称为覆盖查询,MongoDB 只需从索引中获取数据,无需访问磁盘中的文档,极大提高查询性能。

示例:创建复合索引

db.users.createIndex({ name: 1, age: 1 })

查询可以直接使用索引覆盖

db.users.find({ name: "Alice" }, { name: 1, age: 1, _id: 0 })

作用

  • 查询的 nameage 都在索引中,且查询不包含额外字段,因此是覆盖查询,性能更优。

10. 多键索引(Multikey Index)

多键索引用于数组字段,使得查询数组中的元素更高效。

示例:数组字段索引

db.products.createIndex({ tags: 1 })

查询

db.products.find({ tags: "electronics" })

作用

  • 允许对数组中的每个元素建立索引,提高查询速度。

总结

索引类型作用适用场景
唯一索引确保字段值唯一唯一用户标识(email、username)
部分索引仅索引符合条件的文档过滤特定条件的文档
稀疏索引仅索引包含字段的文档可选字段
复合索引多字段查询优化组合查询
文本索引文本搜索文章、博客、评论
哈希索引快速等值查询_id、唯一标识字段
地理索引位置查询查找附近地点
TTL 索引自动删除过期数据会话、日志
覆盖索引查询仅使用索引提高查询性能
多键索引数组字段索引标签、分类、兴趣标签

更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *