TTL索引是一種特殊類型的單字段索引,主要用于當(dāng)滿足某個(gè)特定時(shí)間之后自動刪除相應(yīng)的文檔。也就是說集合中的文檔有一定的有效期,超過有效期的文檔就會失效,會被移除。也即是數(shù)據(jù)會過期。過期的數(shù)據(jù)無需保留,這種情形適用于如機(jī)器生成的事件數(shù)據(jù),日志和會話信息等等。本文主要描述TTL索引的使用。
創(chuàng)建方法
db.collection.createIndex(keys, options)
options:
expireAfterSeconds 指定多少秒或者包含日期值的數(shù)組
創(chuàng)建示例
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
何時(shí)失效
在指定的時(shí)間達(dá)到后失效,也即是索引字段的值加上一個(gè)特定的秒數(shù)之后
如果索引字段是一個(gè)數(shù)組,即索引字段上存在著多個(gè)日期值,此時(shí)MongoDB取最小值加上失效時(shí)間(lowest())
對于非日期字段或不包含日期數(shù)組的索引字段,文檔不會失效
對于不包含索引字段的文檔,文檔不會失效
刪除操作
mongod的一個(gè)后臺線程會讀取索引的值并將失效的文檔從集合移除
當(dāng)TTL線程被激活后,可以從db.currentOp()或者從profile觀察到刪除操作
何時(shí)刪除
當(dāng)基于后臺方式創(chuàng)建索引時(shí),TTL線程能夠在索引創(chuàng)建期間開始刪除失效文檔
當(dāng)基于前臺方式創(chuàng)建索引時(shí),TTL線程在索引創(chuàng)建完成后開始刪除失效文檔
TTL索引的刪除不能完全保證失效期后一定刪除,存在一定延遲(取決于mongod的工作負(fù)載)
TTL刪除文檔后臺線程每60s移除失效文檔(因此可能存在已過失效期,文檔還在的情形)
在副本集環(huán)境中,TTL后臺線程僅僅在主副本上工作,輔助副本上由復(fù)制操作實(shí)現(xiàn)
在使用TTL索引查詢時(shí),與使用非TTL索引一樣
一些限制
不能基于已經(jīng)存在索引的字段創(chuàng)建TTL索引以及非日期字段創(chuàng)建TTL索引,文檔不會失效
TTL索引不支持基于多個(gè)字段的復(fù)合索引
不支持定長集合
# mongo --shell localhost:27000 TTLData.js
MongoDB shell version: 3.2.11
connecting to: localhost:27000/test
repSetTest:PRIMARY> addTTLTestData() //添加集合數(shù)據(jù)
Create three records in database each with a create time that is 1 minute apart
Created three test documents, oldest being 4 mins old
Now create a TTL index with expiry of 5 mins on the createDate field as follows
db.ttlTest.ensureIndex({createDate:1}, {expireAfterSeconds:300})
repSetTest:PRIMARY> db.ttlTest.find() //當(dāng)前向集合里插入了3個(gè)文檔
{ "_id" : 1, "createDate" : ISODate("2017-03-10T03:23:01.169Z") }
{ "_id" : 2, "createDate" : ISODate("2017-03-10T03:24:01.169Z") }
{ "_id" : 3, "createDate" : ISODate("2017-03-10T03:25:01.169Z") }
//下面為測試集合上的文檔添加索引,即5分鐘后索引失效
repSetTest:PRIMARY> db.ttlTest.createIndex({createDate:1}, {expireAfterSeconds:300})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1, // Author : Leshami
"numIndexesAfter" : 2, // Blog : http://blog.csdn.net/leshami
"ok" : 1
}
//查找文檔
repSetTest:PRIMARY> db.ttlTest.find()
{ "_id" : 1, "createDate" : ISODate("2017-03-10T03:23:01.169Z") }
{ "_id" : 2, "createDate" : ISODate("2017-03-10T03:24:01.169Z") }
{ "_id" : 3, "createDate" : ISODate("2017-03-10T03:25:01.169Z") }
//當(dāng)指定時(shí)間到期后,文檔被刪除,如下,查詢不到任何文檔
repSetTest:PRIMARY> db.ttlTest.find()