This document provides an introduction to MongoDB's "time to live" or TTL collection feature. 本文档介绍了MongoDB的“生存时间”或TTL集合功能。TTL collections make it possible to store data in MongoDB and have the TTL集合使在MongoDB中存储数据成为可能,并使mongod automatically remove data after a specified number of seconds or at a specific clock time.mongod在指定的秒数或特定的时钟时间后自动删除数据。
You can expire data for deployments hosted in the following environments:您可以使在以下环境中托管的部署的数据过期:
- MongoDB Atlas
: The fully managed service for MongoDB deployments in the cloud:云中MongoDB部署的完全托管服务
- MongoDB Enterprise
: The subscription-based, self-managed version of MongoDB:MongoDB的基于订阅的自我管理版本 - MongoDB Community
: The source-available, free-to-use, and self-managed version of MongoDB:MongoDB的源代码可用、免费使用和自我管理版本
Data expiration is useful for some classes of information, including machine generated event data, logs, and session information that only need to persist for a limited period of time.数据过期对于某些类别的信息很有用,包括机器生成的事件数据、日志和会话信息,这些信息只需要在有限的时间内持续存在。
A special TTL index property supports the implementation of TTL collections. 一个特殊的TTL索引属性支持TTL集合的实现。The TTL feature relies on a background thread in TTL功能依赖于mongod that reads the date-typed values in the index and removes expired documents from the collection.mongod中的一个后台线程,该线程读取索引中的日期类型值,并从集合中删除过期的文档。
To create a TTL index, use 要创建TTL索引,请使用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.createIndex()。指定一个索引字段,该字段可以是日期类型,也可以是包含日期类型值的数组。使用expireAfterSeconds选项以秒为单位指定TTL值。
Note
The TTL index is a single field index. Compound indexes do not support the TTL property. For more information on TTL indexes, see TTL Indexes.TTL索引是一个单字段索引。复合索引不支持TTL属性。有关TTL索引的更多信息,请参阅TTL索引。
You can modify the 您可以使用expireAfterSeconds of an existing TTL index using the collMod command.collMod命令修改现有TTL索引的expireAfterSeconds。
Expire Documents in the MongoDB Atlas UIMongoDB Atlas UI中的过期文档
To expire data in the Atlas UI, follow these steps:要使Atlas UI中的数据过期,请执行以下步骤:
In the MongoDB Atlas UI, go to the Clusters page for your project.在MongoDB Atlas UI中,转到项目的“集群”页面。
Warning
Navigation Improvements In Progress导航改进正在进行中
We're currently rolling out a new and improved navigation experience. If the following steps don't match your view in the Atlas UI, see the preview Atlas documentation.我们目前正在推出一种新的、改进的导航体验。如果以下步骤与Atlas UI中的视图不匹配,请参阅Atlas预览文档。
If it's not already displayed, select the organization that contains your desired project from the Organizations menu in the navigation bar.如果尚未显示,请从导航栏的“组织”菜单中选择包含所需项目的组织。If it's not already displayed, select your project from the Projects menu in the navigation bar.如果尚未显示,请从导航栏中的“项目”菜单中选择项目。If it's not already displayed, click Clusters in the sidebar.如果尚未显示,请单击侧栏中的“集群”。The Clusters page displays.将显示“群集”页面。
Navigate to the collection导航到集合
For the cluster that contains the data you want to expire, click Browse Collections.对于包含要过期的数据的群集,单击“浏览集合”。In the left navigation pane, select the database.在左侧导航窗格中,选择数据库。In the left navigation pane, select the collection.在左侧导航窗格中,选择集合。
Open the Create Index modal打开“创建索引”模式
Click the Indexes tab.单击“索引”选项卡。Click Create Index.单击“创建索引”。
Create the index with the expiresAfterSeconds option使用expiresAfterSeconds选项创建索引
expiresAfterSeconds optionIn the Fields section, enter the index key specification document. For this example, enter the following text to create an index on the在“字段”部分,输入索引键规范文档。对于此示例,输入以下文本以在expiresAfterfield:expiresAfter字段上创建索引:{ "expiresAfter": 1 }In the Options section, enter the在“选项”部分,输入expireAfterSecondsoption. For this example, enter the following text to expire the data 1 second after theexpiresAfterfield's value:expireAfterSeconds选项。对于此示例,在expiresAfter字段值后1秒输入以下文本以使数据过期:{ expireAfterSeconds: 1 }Click Review.单击“审阅”。Click Confirm.单击“确认”。
Add a document that contains the expiresAfter field to the collection将包含expiresAfter字段的文档添加到集合中
expiresAfter field to the collectionIn the left navigation pane, select the collection that contains the index.在左侧导航窗格中,选择包含索引的集合。Click the Find tab.单击查找选项卡。Click Insert Document.单击“插入文档”。Click the text field under the _id field and enter the field name单击expiresAfter._id字段下的文本字段,然后输入字段名称expiresAfter。Click the text field next to单击expiresAfterand enter the following value:expiresAfter旁边的文本字段,然后输入以下值:2023-10-01T12:00:00.000+00:00This value expires data after 12:00 on October 1, 2023.此值在2023年10月1日12:00之后过期。Click the data type drop-down menu and change the data type value to Date.单击数据类型下拉菜单,将数据类型值更改为日期。Click Insert.单击“插入”。The document will expire automatically one second after the文档将在expiredAfterfield's value.expiredAfter字段值后一秒自动过期。The TTL index may take 1-2 seconds to expire the document. You may need to refresh the UI to see that MongoDB Atlas deletes the expired document.TTL索引可能需要1-2秒才能使文档过期。您可能需要刷新UI才能看到MongoDB Atlas删除了过期的文档。
Expire Documents after a Specified Number of Seconds在指定秒数后过期文档
You can expire documents after a specified number of seconds through collection creation options or a TTL index.您可以通过集合创建选项或TTL索引在指定秒数后使文档过期。
Specify Expiration at Collection Creation指定集合创建时的过期时间
To specify expiration time at collection creation, use the expireAfterSeconds option when you create your collection.要在创建集合时指定过期时间,请在创建集合后使用expireAfterSeconds选项。
Note
The expireAfterSeconds option is only available for time series collections and clustered collections.expireAfterSeconds选项仅适用于时间序列集合和群集集合。
Specify Expiration with a TTL Index使用TTL索引指定到期时间
To expire data after a specified number of seconds has passed since the indexed field, create a TTL index on a field that holds values of BSON date type or an array of BSON date-typed objects and specify a value greater or equal to zero in the 要在索引字段后经过指定秒数后过期数据,请在包含BSON日期类型值或BSON日期型对象数组的字段上创建TTL索引,并在expireAfterSeconds field. expireAfterSeconds字段中指定一个大于或等于零的值。A document will expire when the number of seconds in the 当expireAfterSeconds field has passed since the time specified in its indexed field. expireAfterSeconds字段中的秒数超过其索引字段中指定的时间后,文档将过期。[1]
The TTL index TTL索引expireAfterSeconds value must be within 0 and 2147483647 inclusive.expireAfterSeconds值必须在0和2147483647之间(包括0和21474647)。
For example, the following operation creates an index on the 例如,以下操作在log_events collection's createdAt field and specifies the expireAfterSeconds value of 10 to set the expiration time to be ten seconds after the time specified by createdAt.log_events集合的createdAt字段上创建索引,并指定expireAfterSeconds值10,以将过期时间设置为createdAt指定时间后的10秒。
db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 10 } )
When adding documents to the 将文档添加到log_events collection, set the createdAt field to the current time:log_events集合时,将createdAt字段设置为当前时间:
db.log_events.insertOne( {
"createdAt": new Date(),
"logEvent": 2,
"logMessage": "Success!"
} )
MongoDB will automatically delete documents from the 当文档的log_events collection when the document's createdAt value [1] is older than the number of seconds specified in expireAfterSeconds.createdAt值[1]早于expireAfterSeconds中指定的秒数时,MongoDB将自动从log_events集合中删除文档。
| [1] | (1, 2) expireAfterSeconds.expireAfterSeconds中指定的秒数,则数据将过期。 |
Expire Documents with Filter Conditions使用筛选条件过期文档
To expire documents with specific filter expressions, you can create an index that is both a partial and a TTL index.要使用特定的筛选表达式使文档过期,您可以创建一个既是部分索引又是TTL索引的索引。
Create a partial TTL index:创建部分TTL索引:
db.foo.createIndex(
{ F: 1 },
{
name: "Partial-TTL-Index",
partialFilterExpression: { D : 1 },
expireAfterSeconds: 10
}
)
Insert two documents, one of which matches the filter expression 插入两个文档,其中一个与{ D : 1 } of the partialFilterExpression:partialFilterExpression的筛选表达式{ D : 1 }匹配:
db.foo.insertMany( [
{ "F" : ISODate("2019-03-07T20:59:18.428Z"), "D" : 3},
{ "F" : ISODate("2019-03-07T20:59:18.428Z"), "D" : 1}
] )
Wait for ten seconds then query the 等待10秒,然后查询foo collection:foo集合:
db.foo.find({}, {_id: 0, F: 1, D: 1})
The document that matches the 与partialFilterExpression of { D : 1 } is deleted (expired). As a result, only one document remains in the foo collection:{ D : 1 }的partialFilterExpression匹配的文档已被删除(过期)。因此,foo集合中只剩下一个文档:
{ "F" : ISODate("2019-03-07T20:59:18.428Z"), "D" : 3}Expire Documents at a Specific Clock Time在特定时钟时间过期文档
You can expire data at a specified clock time in the terminal. To expire documents at a specific clock time, begin by creating a TTL index on a field that holds values of BSON date type or an array of BSON date-typed objects and specify an 您可以在终端中的指定时钟时间过期数据。要在特定时钟时间过期文档,请首先在包含BSON日期类型值或BSON日期型对象数组的字段上创建TTL索引,并指定expireAfterSeconds value of 0. expireAfterSeconds值为0。For each document in the collection, set the indexed date field to a value corresponding to the time the document should expire. If the indexed date field contains a date in the past, MongoDB considers the document expired.对于集合中的每个文档,将索引日期字段设置为与文档到期时间对应的值。如果索引日期字段包含过去的日期,MongoDB将认为文档已过期。
For example, the following operation creates an index on the 例如,以下操作在log_events collection's expireAt field and specifies the expireAfterSeconds value of 0:log_events集合的expireAt字段上创建索引,并指定expireAfterSeconds值为0:
db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
For each document, set the value of 对于每个文档,将expireAt to correspond to the time the document should expire. For example, the following insertOne() operation adds a document that expires at July 22, 2013 14:00:00.expireAt的值设置为与文档应过期的时间相对应。例如,以下insertOne()操作添加了一个在July 22, 2013 14:00:00到期的文档。
db.log_events.insertOne( {
"expireAt": new Date('July 22, 2013 14:00:00'),
"logEvent": 2,
"logMessage": "Success!"
} )
MongoDB will automatically delete documents from the 当文档的log_events collection when the documents' expireAt value is older than the number of seconds specified in expireAfterSeconds, i.e. 0 seconds older in this case. expireAt值早于expireAfterSeconds中指定的秒数时,MongoDB将自动从log_events集合中删除文档,即在这种情况下早0秒。As such, the data expires at the specified 因此,数据在指定的expireAt value.expireAt值处过期。
Indexes Configured Using NaN使用NaN配置的索引
Warning
Possible Data Loss可能的数据丢失
When a TTL index has 当TTL索引的expireAfterSeconds set to NaN, upgrade, downgrade, and certain syncing operations can lead to unexpected behavior and possible data loss.expireAfterSeconds设置为NaN时,升级、降级和某些同步操作可能会导致意外行为和可能的数据丢失。
Do not set 请勿在TTL索引配置中将expireAfterSeconds to NaN in your TTL index configuration.expireAfterSeconds设置为NaN。
Prior to MongoDB 5.0, when a TTL index has 在MongoDB 5.0之前,当TTL索引的expireAfterSeconds set to NaN, MongoDB logs an error and does not remove any records.expireAfterSeconds设置为NaN时,MongoDB会记录错误,并且不会删除任何记录。
From MongoDB 5.0.0 - 5.0.13 (and 6.0.0 - 6.0.1), 从MongoDB 5.0.0到5.0.13(和6.0.0到6.0.1),NaN is treated as 0. If a TTL index is configured with expireAfterSeconds set to NaN, all TTL-indexed documents expire immediately.NaN被视为0。如果TTL索引配置为expireAfterSeconds设置为NaN,则所有TTL索引文档都会立即过期。
Starting in MongoDB 5.0.14 (and 6.0.2), the server will not use TTL indexes that have 从MongoDB 5.0.14(和6.0.2)开始,服务器将不使用expireAfterSeconds set to NaN.expireAfterSeconds设置为NaN的TTL索引。
However, there are still some situations which may result in unexpected behavior. Documents may expire:然而,仍有一些情况可能会导致意外行为。文件可能会过期:
During an initial sync to an earlier version from MongoDB 5.0.0 - 5.0.13 (or 6.0.0 - 6.0.1).在从MongoDB 5.0.0到5.0.13(或6.0.0到6.0.1)的早期版本的初始同步期间。When upgrading from an earlier version to MongoDB 5.0.0 - 5.0.13.从早期版本升级到MongoDB 5.0.0-5.0.13时。When restoring a collection from a pre-5.0将集合从5.0之前的mongodumpinto a MongoDB 5.0.0 - 5.0.13 (or 6.0.0 - 6.0.1) instance.mongodump还原到MongoDB 5.0.0-5.0.13(或6.0.0-6.0.1)实例时。
To avoid problems, either drop or correct any misconfigured TTL indexes.为避免出现问题,请删除或更正任何配置错误的TTL索引。
Identify misconfigured indexes.识别配置错误的索引。
Run the following script in the 在mongosh shell. The script does not work in the legacy mongo shell.mongosh shell中运行以下脚本。该脚本在遗留的mongo shell中不起作用。
function getNaNIndexes() {
const nan_index = [];
const dbs = db.adminCommand({ listDatabases: 1 }).databases;
dbs.forEach((d) => {
if (d.name != 'local') {
const listCollCursor = db
.getSiblingDB(d.name)
.runCommand({ listCollections: 1 }).cursor;
const collDetails = {
db: listCollCursor.ns.split(".$cmd")[0],
colls: listCollCursor.firstBatch.map((c) => c.name),
};
collDetails.colls.forEach((c) =>
db
.getSiblingDB(collDetails.db)
.getCollection(c)
.getIndexes()
.forEach((entry) => {
if (Object.is(entry.expireAfterSeconds, NaN)) {
nan_index.push({ ns: `${collDetails.db}.${c}`, index: entry });
}
})
);
}
});
return nan_index;
};
getNaNIndexes();Correct misconfigured indexes.更正配置错误的索引。
Use the 使用collMod command to update any misconfigured expireAfterSeconds values that the script found.collMod命令更新脚本发现的任何配置错误的expireAfterSeconds值。
As an alternative, you can 作为替代方案,您可以删除任何配置错误的TTL索引,稍后使用drop any misconfigured TTL indexes and recreate them later using the createIndexes command.createIndexes命令重新创建它们。