TTL IndexesTTL索引
On this page本页内容
If you are removing documents to save on storage costs, consider Online Archive in MongoDB Atlas如果您要删除文档以节省存储成本,请考虑MongoDB Atlas.
中的在线存档。
Online Archive automatically archives infrequently accessed data to fully-managed S3 buckets for cost-effective data tiering.在线归档会自动将不常访问的数据归档到完全管理的S3存储桶中,以实现经济高效的数据分层。
TTL indexes are special single-field indexes that MongoDB can use to automatically remove documents from a collection after a certain amount of time or at a specific clock time. TTL索引是一种特殊的单字段索引,MongoDB可以使用它在一定时间后或特定的时钟时间自动从集合中删除文档。Data expiration is useful for certain types of information like machine generated event data, logs, and session information that only need to persist in a database for a finite amount of time.数据过期对于某些类型的信息很有用,如机器生成的事件数据、日志和会话信息,这些信息只需要在数据库中保留有限的时间。
Create a TTL Index创建TTL索引
After you create a TTL index, it might have a very large number of qualifying documents to delete at once. 创建TTL索引后,可能会同时删除大量符合条件的文档。This large workload might cause performance issues on the server. 如此大的工作负载可能会导致服务器出现性能问题。To avoid these issues, plan to create the index during off hours, or delete qualifying documents in batches before you create the index for future documents.为了避免这些问题,请计划在下班时间创建索引,或者在为将来的文档创建索引之前批量删除符合条件的文档。
To create a TTL index, use 要创建TTL索引,请使用createIndex()
. createIndex()
。Specify an index field that is either a date type or an array that contains date type values. 指定一个索引字段,该字段可以是日期类型,也可以是包含日期类型值的数组。Use the 使用expireAfterSeconds
option to specify a TTL value in seconds.expireAfterSeconds
选项可以指定以秒为单位的TTL值。
The TTL index TTL索引expireAfterSeconds
value must be within 0
and 2147483647
inclusive.expireAfterSeconds
值必须介于0
和2147483647
之间(包括0
和2147463647
)。
For example, to create a TTL index on the 例如,要在lastModifiedDate
field of the eventlog
collection with a TTL value of 3600
seconds, use the following operation in mongosh
:eventlog
集合的lastModifiedDate
字段上创建TTL值为3600
秒的TTL索引,请在mongosh
中使用以下操作:
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
Starting in MongoDB 6.3, you can create partial TTL indexes on time series collections. 从MongoDB 6.3开始,您可以在时间序列集合上创建部分TTL索引。These indexes use the collection 这些索引使用集合timeField
as the key field, and require a partial filter expression on the metaField
.timeField
作为键字段,并且需要在metaField
上使用部分筛选器表达式。
Time series collections include an optional 时间序列集合包括一个可选的expireAfterSeconds
field. expireAfterSeconds
字段。If you do not set it, a TTL index with a 如果不进行设置,则可以使用带有partialFilterExpression
lets you set an expiration period for documents that match the filter. partialFilterExpression
的TTL索引为与筛选器匹配的文档设置过期期。If you do set 如果您确实设置了expireAfterSeconds
, a partial TTL index lets you set a different, shorter expiration period for matching documents. expireAfterSeconds
,则部分TTL索引允许您为匹配的文档设置不同的、更短的过期期。You can only create a 您只能在partialFilterExpression
on the metaField
.metaField
上创建一个partialFilterExpression
。
If the 如果集合的expireAfterSeconds
value of the collection is lower than the expireAfterSeconds
of the partial TTL index, the collection deletes documents after the shorter time, so the TTL index has no effect.expireAfterSeconds
值低于部分TTL索引的expireAfterSeconds
,则集合会在较短的时间后删除文档,因此TTL索引无效。
This weather data time series collection deletes documents after 24 hours:此天气数据时间序列集合在24小时后删除文档:
db.createCollection(
"weather24h",
{
timeseries: {
timeField: "timestamp",
metaField: "sensor",
granularity: "hours"
},
expireAfterSeconds: 86400})
This TTL index deletes documents from the MongoDB NYC headquarters weather sensor after 1 hour, instead of 24 hours:此TTL索引在1小时后而不是24小时后从MongoDB NYC总部天气传感器中删除文档:
db.eventlog.createIndex(
{ "timestamp": 1 },
{ partialFilterExpression: { "sensor": { $eq: "40.761873, -73.984287" } } },
{ expireAfterSeconds: 3600 } )
Convert a non-TTL single-field Index into a TTL Index将非TTL单字段索引转换为TTL索引
Starting in MongoDB 5.1, you can add the 从MongoDB 5.1开始,您可以将expireAfterSeconds
option to an existing single-field index. expireAfterSeconds
选项添加到现有的单个字段索引中。To change a non-TTL single-field index to a TTL index, use the 要将非TTL单字段索引更改为TTL索引,请使用collMod
database command:collMod
数据库命令:
db.runCommand({
"collMod": <collName>,
"index": {
"keyPattern": <keyPattern>,
"expireAfterSeconds": <number>
}
})
The following example converts a non-TTL single-field index with the pattern 以下示例将模式为{ "lastModifiedDate": 1 }
into a TTL index:{ "lastModifiedDate": 1 }
的非TTL单字段索引转换为TTL索引:
db.runCommand({
"collMod": "tickets",
"index": {
"keyPattern": { "lastModifiedDate": 1 },
"expireAfterSeconds": 100
}
})
Change the expireAfterSeconds
value for a TTL Index更改TTL索引的expireAfterSeconds
值
expireAfterSeconds
value for a TTL IndexTo change the 要更改TTL索引的expireAfterSeconds
value for a TTL Index, use the collMod
database command:expireAfterSeconds
值,请使用collMod
数据库命令:
db.runCommand({
"collMod": <collName>,
"index": {
"keyPattern": <keyPattern>,
"expireAfterSeconds": <number>
}
})
The following example changes the 以下示例更改expireAfterSeconds
value for an index with the pattern { "lastModifiedDate": 1 }
on the tickets
collection:ticket
s集合上具有模式{ "lastModifiedDate": 1 }
的索引的expireAfterSeconds
值:
db.runCommand({
"collMod": "tickets",
"index": {
"keyPattern": { "lastModifiedDate": 1 },
"expireAfterSeconds": 100
}
})
Behavior行为
Expiration of Data数据过期
TTL indexes expire documents after the specified number of seconds has passed since the indexed field value; i.e. the expiration threshold is the indexed field value plus the specified number of seconds.TTL索引使文档在从索引字段值起经过指定秒数后过期;即,过期阈值是索引字段值加上指定的秒数。
If the field is an array, and there are multiple date values in the index, MongoDB uses lowest (i.e. earliest) date value in the array to calculate the expiration threshold.如果字段是一个数组,并且索引中有多个日期值,MongoDB会使用数组中最低(即最早)的日期值来计算过期阈值。
For time series collections, TTL indexes also remove a bucket of data when all documents inside it expire. 对于时间序列集合,TTL索引还会在其中的所有文档过期时删除一个数据桶。This is equal to the upper timestamp limit of the bucket, plus the 这等于桶的时间戳上限加上expireAfterSeconds
value. expireAfterSeconds
值。For example, if a bucket covers data up until 例如,如果存储桶覆盖的数据直到2023-03-27T18:29:59Z
and expireAfterSeconds
is 300, the TTL index expires the bucket after 2023-03-27T18:34:59Z
.2023-03-27T18:29:59Z
,并且expireAfterSeconds
为300
,则TTL索引将在2023-03-27T18:34:59Z
之后使存储桶过期。
If the indexed field in a document is not a date or an array that holds one or more date values, the document will not expire.如果文档中的索引字段不是日期或包含一个或多个日期值的数组,则文档不会过期。
If a document does not contain the indexed field, the document will not expire.如果文档不包含索引字段,则该文档不会过期。
Delete Operations删除操作
A background thread in mongod
reads the values in the index and removes expired documents from the collection.mongod
中的后台线程读取索引中的值,并从集合中删除过期的文档。
When the TTL thread is active, you will see delete operations in the output of 当TTL线程处于活动状态时,您将在db.currentOp()
or in the data collected by the database profiler.db.currentOp()
的输出或数据库探查器集合的数据中看到删除操作。
Starting in MongoDB 6.1:从MongoDB 6.1开始:
To improve efficiency, MongoDB may batch multiple document deletions together.为了提高效率,MongoDB可以将多个文档删除一起批处理。Theexplain
command results contain a newBATCHED_DELETE
stage for batched document deletions.explain
命令结果包含一个新的BATCHED_DELETE
阶段,用于批量删除文档。
Timing of the Delete Operation删除操作的时间
MongoDB begins removing expired documents or time series buckets as soon as the index finishes building on the primary. 一旦索引在primary上构建完成,MongoDB就开始删除过期的文档或时间序列存储桶。For more information on the index build process, see Index Builds on Populated Collections.有关索引生成过程的详细信息,请参阅填充集合上的索引生成。
The TTL index does not guarantee that expired data is deleted immediately upon expiration. TTL索引不能保证过期的数据在过期后立即删除。There may be a delay between the time that a document expires and the time that MongoDB removes the document from the database.文档过期和MongoDB从数据库中删除文档之间可能存在延迟。
The background task that removes expired documents runs every 60 seconds. 删除过期文档的后台任务每60秒运行一次。As a result, documents may remain in a collection during the period between the expiration of the document and the running of the background task. 因此,在文档到期和后台任务运行之间的时间段内,文档可能会保留在集合中。MongoDB starts deleting documents 0 to 60 seconds after the index completes.MongoDB在索引完成后0到60秒开始删除文档。
Because the duration of the removal operation depends on the workload of your 由于删除操作的持续时间取决于mongod
instance, expired data may exist for some time beyond the 60 second period between runs of the background task.mongod
实例的工作负载,因此过期数据可能会存在一段时间,超过后台任务运行之间的60秒。
The delete operations initiated by the TTL task run in the foreground, like other deletes.TTL任务启动的删除操作与其他删除操作一样在前台运行。
Replica Sets复制集
On replica set members, the TTL background thread only deletes documents when a member is in state primary. 在副本集成员上,TTL后台线程仅在成员处于主状态时删除文档。The TTL background thread is idle when a member is in state secondary. Secondary members replicate deletion operations from the primary.当成员处于secondary状态时,TTL后台线程处于空闲状态。secondary成员从主成员复制删除操作。
Support for Queries对查询的支持
A TTL index supports queries in the same way non-TTL indexes do.TTL索引以与非TTL索引相同的方式支持查询。
Restrictions限制
TTL indexes are single-field indexes.TTL索引是单字段索引。Compound indexes do not support TTL and ignore the复合索引不支持TTL,并忽略expireAfterSeconds
option.expireAfterSeconds
选项。The_id
field does not support TTL indexes._id
字段不支持TTL索引。You cannot create a TTL index on a capped collection.不能在封顶集合上创建TTL索引。You can only create TTL indexes for a time series collection on the collection只能在集合timeField
.timeField
上为时间序列集合创建TTL索引。You cannot use不能使用createIndex()
to change the value ofexpireAfterSeconds
of an existing index.createIndex()
更改现有索引的expireAfterSeconds
的值。Instead use the请改用collMod
database command.collMod
数据库命令。See Change the请参阅更改TTL索引的expireAfterSeconds
value for a TTL Index.expireAfterSeconds
值。If a non-TTL single-field index already exists for a field, you cannot create a TTL index on the same field since you cannot create indexes that have the same key specification and differ only by the options.如果某个字段已经存在非TTL单字段索引,则不能在同一字段上创建TTL索引,因为不能创建具有相同键规范且仅选项不同的索引。To change a non-TTL single-field index to a TTL index, use the要将非TTL单字段索引更改为TTL索引,请使用collMod
database command.collMod
数据库命令。