在 MongoDB 中,索引的添加可以通过多种方式实现。以下是分别在 Python 的 pymongo 和 Java 的 Spring Boot(spring-boot-starter-data-mongodb) 中添加索引的方法:
1. 在 pymongo 中添加索引
基本语法
python
from pymongo import MongoClient, ASCENDING, DESCENDING
client = MongoClient("mongodb://localhost:27017/")
db = client["mydb"]
collection = db["users"]
# 添加索引
collection.create_index([(字段名, 排序方向)], 选项参数)
常见场景
单字段索引
python
# 添加升序索引(默认方向为 ASCENDING)
collection.create_index([("email", ASCENDING)], unique=True, name="email_unique_idx")
# 添加降序索引
collection.create_index([("createdAt", DESCENDING)])
复合索引
python
# 添加复合索引(name 升序 + age 降序)
collection.create_index(
[("name", ASCENDING), ("age", DESCENDING)],
name="name_age_idx"
)
TTL 索引(自动过期)
python
# 添加 TTL 索引(文档在 3600 秒后自动删除)
collection.create_index(
[("expireAt", ASCENDING)],
expireAfterSeconds=3600,
name="expire_ttl_idx"
)
后台创建索引(避免阻塞操作)
python
# 后台异步创建索引(适合生产环境)
collection.create_index(
[("phone", ASCENDING)],
background=True,
name="phone_idx"
)
参数说明
参数 | 说明 |
---|---|
unique=True |
唯一索引 |
name="index_name" |
自定义索引名称(默认自动生成,如 email_1 ) |
background=True |
后台创建索引(避免阻塞其他操作) |
expireAfterSeconds |
TTL 索引的过期时间(单位:秒) |
sparse=True |
稀疏索引(仅索引包含字段的文档) |
2. 在 Spring Boot 中添加索引
使用 spring-boot-starter-data-mongodb
时,可以通过 注解 或 编程方式 添加索引。
方法 1:注解声明式索引
在实体类(Entity)中使用 @Indexed
和 @CompoundIndex
注解:
单字段索引
java
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "users")
public class User {
@Id
private String id;
@Indexed(unique = true, name = "email_unique_idx")
private String email;
@Indexed(name = "createdAt_idx", expireAfterSeconds = 3600)
private Date createdAt;
}
复合索引
java
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.CompoundIndexes;
@Document(collection = "users")
@CompoundIndexes({
@CompoundIndex(
name = "name_age_idx",
def = "{'name': 1, 'age': -1}"
)
})
public class User {
// 字段定义...
}
方法 2:编程方式动态创建索引
在 Spring Boot 启动时,通过 MongoTemplate
手动创建索引:
java
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.Index;
import javax.annotation.PostConstruct;
public class MongoIndexConfig {
private final MongoTemplate mongoTemplate;
public MongoIndexConfig(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
@PostConstruct
public void initIndexes() {
// 单字段索引
Index emailIndex = new Index().on("email", Direction.ASC)
.unique().named("email_unique_idx");
mongoTemplate.indexOps("users").ensureIndex(emailIndex);
// 复合索引
Index nameAgeIndex = new Index()
.on("name", Direction.ASC)
.on("age", Direction.DESC)
.named("name_age_idx");
mongoTemplate.indexOps("users").ensureIndex(nameAgeIndex);
// TTL 索引
Index expireAtIndex = new Index().on("expireAt", Direction.ASC)
.expire(3600).named("expire_ttl_idx");
mongoTemplate.indexOps("users").ensureIndex(expireAtIndex);
}
}
参数说明
注解或方法 | 说明 |
---|---|
@Indexed(unique=true) |
唯一索引 |
@Indexed(name="idx_name") |
自定义索引名称 |
@CompoundIndex |
定义复合索引 |
expireAfterSeconds |
TTL 索引的过期时间 |
Index().expire(seconds) |
编程方式设置 TTL 时间 |
3. 注意事项
- 唯一性约束 :唯一索引插入重复数据时会抛出异常(如
DuplicateKeyException
)。 - 索引性能 :
• 添加索引会占用存储空间,并在写入时增加开销。
• 生产环境建议通过background=True
(pymongo)或后台异步操作(Spring Boot)创建索引。 - 索引覆盖:尽量使用复合索引覆盖高频查询的字段组合。
- Spring Boot 自动创建 :
• 默认情况下,Spring Boot 会在应用启动时自动创建注解声明的索引。
• 可通过配置关闭自动索引创建:spring.data.mongodb.auto-index-creation=false
4. 验证索引
• pymongo :使用 collection.index_information()
查看所有索引。
• Spring Boot :通过 MongoDB Compass 或 mongo shell
执行 db.collection.getIndexes()
。
通过以上方法,可以在两种技术栈中高效管理 MongoDB 索引,优化查询性能。