一、TTL 索引简介
TTL 索引能对单列值设置过期属性,实现对文档过期后自动删除
二、TTL 索引的限制
以下几种情况,不能使用 TTL 索引,或者使用后 TTL 索引不生效:
- 如果设置的索引字段不是 date 类型的,则设置后 TTL 索引不生效
- 如果索引字段的值为 null 或者没有索引字段,则设置后 TTL 索引不生效
- TTL 索引只支持单字段索引,符合索引不支持
- _id 字段不支持 TTL 索引
- 不能同时对一个字段创建普通索引和 TTL 索引(TTL 索引本质就是普通索引,只是多了个过期的属性配置)
- 如果一个字段已经存在了普通索引,如果想对这个字段创建 TTL 索引,需要先删除普通索引
三、TTL 索引的执行原理
- mongoDB 会在后台开启一个线程,该线程每隔 60s 会触发一次删除任务,将已经过期的文档进行删除
1、如果数据量较大,可能会存在数据到期后未及时删除的情况,所以 TTL 索引不能适用于对时间要求非常严格的场景
2、应尽量避免数据在同一时间内集中过期
- 在 mongoDB 的副本集中,TTL 的线程线程只会在 primary 节点开启,从节点要删除的数据,是从主节点的 oplog 日志来同步的
四、TTL 索引的使用
1、创建索引时指定过期时间
db.collectionName.createIndex({
"deadlineDate": 1
}, {
expireAfterSeconds: 3600
});
-
通过 expireAfterSeconds 指定索引的过期时间为 3600s
-
插入数据,数据将在插入后 3600s 左右过期
db.collectionName.insert({ "deadlineDate": new Date(), "age": 24, "name": "liuqiuyi" });
2、插入数据时指定过期时间
db.collectionName.createIndex({
"deadlineDate": 1
}, {
expireAfterSeconds: 0
});
-
expireAfterSeconds 设置为 0
-
插入数据,通过数据的 deadlineDate 字段指定过期时间
db.collectionName.insert({ "deadlineDate": ISODate("2020-12-21T11:46:42.477Z"), "age": 24, "name": "liuqiuyi" });以上表示该文档将在 2020-12-21 11:46:42 左右被自动删除
3、修改 TTL 索引
// 修改索引定义,将文档的过期时间改为60秒
db.runCommand( { collMod: "collectionName",
index: { keyPattern: { deadlineDate: 1 },
expireAfterSeconds: 60
}