通过mongodb的TTL机制,集合中的数据可以自动过期删除TTL可以让mongodb自动清除过期数据(咦,这不正好满足日志类的数据要求吗)。这种机制比较适合一些日志数据机产生的事件数据,甚至可以作为session会话。MongoDB通过一个TTL索引来实现这个所谓的TTL集合。该特性的实现机制是:mongod使用后台线程不断读取集合中某个日期类型的索引,移除满足过期条件的文档。让我们看看如何实际操作:要创建TTL索引,我们使用带有expireAfterSeconds选项的db.collection.createIndex()命令为集合中的字段创建TTL索引。该字段必须是日期类型或包含日期类型值的数组字段。创建TTL过期规则有两种模式:一种类似于前端的maxAge模式,即设置一个时长,当mongodb发现当前时间与时间索引字段的时间差超过maxAge时,会视为过期;另一种是类似于前端的expireTime模式。即设置一个过期时间点。当mongodb发现当前系统时间已经超过了那个时间点,就会认为记录过期了。下面分别看看两种模式的设置方法。特定时间段后删除文件如果我们在db中有一个日志集合,记录格式为:{"_id":"5f43d5c00b34962beb026aad","createdAt":Date(),"requestTime":1598281152423,"reportId":"1598281152423-6245975993217447",}接下来,我们为createdAt字段创建TTL索引:db.logs.createIndex({"createdAt":1},{expireAfterSeconds:3600})其中createdAt:1表示createdAt字段建立正序指数。选项expireAfterSeconds表示在3600秒(即1小时)后过期。它的意思是,以createdAt字段的值的时间为基准,加上3600秒后,时间到期。测试一下。我让过期时间为10秒并做了测试。以下是测试结果:在特定时间点删除文档有时,我们不想在文档创建后多少秒后删除它。而是希望在每天早上的某个时间进行日志删除(比如避开用户访问的高峰期)。因此,我们要为文档指定一个特定的到期点。这个规则,mongodb也可以设置。当我们创建TTL索引时,只需要将expireAfterSeconds配置值设置为0即可。当然,为了让我们的索引字段名副其实,我们重新设计了数据源(比如我们将这个TTL索引字段命名为过期删除时间)。数据记录的结构现在如下所示:{"_id":"5f43d5c00b34962beb026aad","expireDeleteTime":ISODate("2020-09-02T11:44:11.528Z"),"requestTime":1598281152423,"reportId":"1551324275492",}然后,我们创建expireDeleteTime字段的TTL索引,方法如下:db.expireAfterSeconds为0,那么这意味着mongodb会以index字段【expireDeleteTime中的时间值加上0秒】作为判断依据,而此时的判断依据其实就是expireDeleteTime字段本身。此时,我们向库中插入一条当前时间的记录(这意味着该记录将立即过期)。然后一直查询集合,看到如下结果:最后,数据记录被自动删除了。但其实我插入的数据应该是在插入的那一刻就过期了(因为它的expireAfterSeconds时间就是此时),但是可以发现mongodb并没有立即删除数据,而是在大约60秒后删除,也就是因为mongodb后台线程的检测间隔是60秒。第二种过期方式对我们的日志数据来说是非常有价值的。我们可以在每条记录存入数据库的时候,加上一个expireTime字段来标记记录的过期时间。比如我们希望日志记录保存15天,可以使用moment类库来实现://计算过期时间constexpireTime=moment().add(15,'days').endOf('day')//将过期时间点和日志数据存储db.insert({expireTime,...logData})MongoDB会自动删除集合中expireTime字段晚于当前时间的记录。因此可以达到15天后自动删除日志的效果。综上所述,MongoDb可以通过创建TTL索引实现过期数据的删除。当索引配置项expireAfterSeconds,即过期时间设置为0秒时,就实现了灵活设置文档过期时间的目的。
