Nota
Si vas a eliminar documentos para ahorrar en costos de almacenamiento, considera Online Archive en MongoDB Atlas. Online Archive archiva automáticamente los datos a los que se accede con poca frecuencia en buckets S3 totalmente gestionados para una nivelación de datos rentable.
Los "Time-to-live" (TTL) Ãndices son Ãndices especiales de un solo campo que MongoDB puede utilizar para remover automáticamente documentos de una colección después de un cierto perÃodo de tiempo o a una hora especÃfica. La expiración de datos es útil para ciertos tipos de información, como los datos de eventos generados por máquinas, los registros y la información de sesiones, que solo necesitan persistir en una base de datos durante un tiempo finito.
Cree un Ãndice TTL
Advertencia
Después de crear un Ãndice TTL, es posible que tenga una gran cantidad de documentos que cumplan con los requisitos para borrar de una vez. Esta gran carga de trabajo podrÃa causar problemas de rendimiento en el servidor. Para evitar estos problemas, planifica crear el Ãndice durante horas no laborables o borra los documentos calificados en grupos antes de crear el Ãndice para documentos futuros.
Para crear un Ãndice TTL, utiliza createIndex(). Especifica un campo de Ãndice que sea un tipo de fecha o un arreglo que contenga valores de tipo de fecha. Utiliza la opción expireAfterSeconds para especificar un valor de TTL en segundos.
El valor del Ãndice TTL expireAfterSeconds debe estar entre 0 y 2147483647, inclusive.
Por ejemplo, para crear un Ãndice TTL en el campo lastModifiedDate de la colección eventlog con un valor TTL de 3600 segundos, utilice la siguiente operación en mongosh:
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
A partir de MongoDB 7.0, puedes crear Ãndices TTL parciales en colecciones de series de tiempo. Estos Ãndices utilizan la colección timeField como campo clave y requieren una expresión de filtro parcial en el metaField.
Las colecciones de series de tiempo incluyen un campo opcional expireAfterSeconds. Si no se establece expireAfterSeconds, un Ãndice TTL con una partialFilterExpression permite establecer un perÃodo de expiración para los documentos que coinciden con el filtro. Si se configura expireAfterSeconds, un Ãndice TTL parcial permite establecer un perÃodo de caducidad diferente y más corto para los documentos coincidentes. Solo se puede crear una partialFilterExpression en el metaField.
Importante
Si el valor expireAfterSeconds de la colección es menor que el expireAfterSeconds del Ãndice TTL parcial, la colección borra los documentos después del tiempo más corto, por lo que el Ãndice TTL no tiene efecto.
Si una colección de series de tiempo contiene documentos con marcas de tiempo timeField antes de 1970-01-01T00:00:00.000Z o después de 2038-01-19T03:14:07.000Z, ningún documento se elimina de la colección por la funcionalidad TTL "tiempo de vida".
Esta colección de series de tiempo de datos meteorológicos borra documentos después de 24 horas:
db.createCollection( "weather24h", { timeseries: { timeField: "timestamp", metaField: "sensor", granularity: "hours" }, expireAfterSeconds: 86400 } )
Este Ãndice TTL borra documentos del sensor meteorológico de la sede de MongoDB en Nueva York después de 1 hora, en lugar de 24 horas:
db.weather24h.createIndex( { "timestamp": 1 }, { partialFilterExpression: { "sensor": { $eq: "40.761873, -73.984287" } }, expireAfterSeconds: 3600 } )
Convertir un Ãndice de campo único que no sea TTL en un Ãndice TTL
A partir de MongoDB 5.1, puedes añadir la opción expireAfterSeconds a un Ãndice de campo único existente. Para cambiar un Ãndice de campo único no TTL a un Ãndice TTL, usa el comando de base de datos collMod:
db.runCommand({ "collMod": <collName>, "index": { "keyPattern": <keyPattern>, "expireAfterSeconds": <number> } })
El siguiente ejemplo convierte un Ãndice de un solo campo no-TTL con el patrón { "lastModifiedDate": 1 } en un Ãndice TTL:
db.runCommand({ "collMod": "tickets", "index": { "keyPattern": { "lastModifiedDate": 1 }, "expireAfterSeconds": 100 } })
Cambiar el valor de expireAfterSeconds para un Ãndice TTL
Para cambiar el valor expireAfterSeconds de un Ãndice TTL, usa el comando de base de datos collMod:
db.runCommand({ "collMod": <collName>, "index": { "keyPattern": <keyPattern>, "expireAfterSeconds": <number> } })
El siguiente ejemplo cambia el valor de expireAfterSeconds para un Ãndice con el patrón { "lastModifiedDate": 1 } en la colección tickets:
db.runCommand({ "collMod": "tickets", "index": { "keyPattern": { "lastModifiedDate": 1 }, "expireAfterSeconds": 100 } })
Importante
Considera lo siguiente antes de actualizar el parámetro expireAfterSeconds de un Ãndice TTL:
Cambiar el parámetro
expireAfterSecondsno desencadena una reconstrucción completa del Ãndice. Sin embargo, reducir el valorexpireAfterSecondspuede hacer que muchos documentos sean elegibles para eliminación inmediata, lo que podrÃa causar problemas de rendimiento debido al aumento de las operaciones de eliminación.La recomendación es borrar manualmente los documentos en pequeños grupos antes de actualizar el Ãndice TTL. Esto ayuda a controlar el impacto en el clúster.
Eliminar muchos documentos puede fragmentar los archivos de almacenamiento, además de afectar el rendimiento. Es posible que necesite ejecutar el comando compact en la colección o realizar una sincronización inicial para recuperar espacio y optimizar el almacenamiento.
Comportamiento
Caducidad de los datos
Los Ãndices TTL eliminan los documentos después de que haya transcurrido el número especificado de segundos desde el valor del campo indexado.
Si el campo es un arreglo y hay múltiples valores de fecha en el Ãndice, MongoDB utiliza el valor más bajo (la fecha más temprana) en el arreglo para calcular el umbral de expiración.
Para las colecciones de series de tiempo, los Ãndices TTL también remueven un bucket de datos cuando todos los documentos en su interior expiran. Esto es igual al lÃmite superior de la marca de tiempo del bucket, más el valor de expireAfterSeconds. Por ejemplo, si un bucket cubre datos hasta 2023-03-27T18:29:59Z y expireAfterSeconds es 300, el Ãndice TTL expira el bucket después de 2023-03-27T18:34:59Z.
Si el campo indexado en un documento no es una fecha o un arreglo que contenga uno o más valores de fecha, el documento no caducará.
Si un documento no contiene el campo indexado, el documento no expirará.
Operaciones de borrar
Un hilo en segundo plano en mongod lee los valores del Ãndice y remueve documentos expirados de la colección.
Las operaciones de eliminación en curso realizadas por el subproceso TTL aparecen en la salida de db.currentOp(). A medida que el hilo TTL borra los documentos, incrementa la métrica de estado del servidor metrics.ttl.deletedDocuments.
A partir de MongoDB 6.1:
Para mejorar la eficiencia, MongoDB puede agrupar la eliminación de múltiples documentos.
Los resultados
explaindel comando contienen una nuevaBATCHED_DELETEetapa para la eliminación de documentos agrupados.
Si una colección de series de tiempo contiene documentos con marcas de tiempo timeField antes de 1970-01-01T00:00:00.000Z o después de 2038-01-19T03:14:07.000Z, ningún documento se elimina de la colección por la funcionalidad TTL "tiempo de vida".
Proceso de borrado
El proceso de borrado en segundo plano de TTL verifica cada Ãndice TTL para documentos expirados. Para cada Ãndice TTL, el proceso en segundo plano borra documentos hasta que se cumpla una de las siguientes condiciones:
El proceso borra 50000 documentos del Ãndice actual.
El proceso toma un segundo para borrar documentos del Ãndice actual.
Todos los documentos expirados se borran del Ãndice actual.
Luego, el proceso avanza al siguiente Ãndice. Después de que el proceso pase por cada Ãndice TTL una vez, el subproceso actual se completa y comienza un nuevo subproceso para verificar los documentos expirados restantes. Un pase se completa cuando el supervisor TTL ha borrado todos los documentos candidatos posibles de todos los Ãndices TTL.
Además, el proceso detiene el bucle de borrado actual cada 60 segundos para evitar dedicar demasiado tiempo a un solo borrado grande. Cuando esto ocurre, el subpase actual termina y comienza un nuevo subpase.
Los pases y subpases se rastrean en las métricas de estado del servidor metrics.ttl.passes y metrics.ttl.subPasses, respectivamente.
Momento de la operación de borrar
MongoDB comienza a remover los documentos caducados o los buckets de series de tiempo tan pronto como el Ãndice termina de construirse en el primario. Para obtener más información sobre el proceso de creación de Ãndices, consulta Creación de Ãndices en colecciones pobladas.
El Ãndice TTL no garantiza que los datos expirados se borren inmediatamente tras su expiración. Puede haber un retraso entre el momento en que un documento expira y el momento en que MongoDB lo remueve de la base de datos.
La tarea en segundo plano que remueve los documentos expirados se ejecuta cada 60 segundos. Como resultado, los documentos pueden permanecer en una colección durante el perÃodo entre la expiración del documento y la ejecución de la tarea en segundo plano. MongoDB comienza a borrar documentos entre 0 y 60 segundos después de que el Ãndice se complete.
Debido a que la duración de la operación de remoción depende de la carga de trabajo de la instancia mongod, los datos expirados pueden existir durante algún tiempo después del perÃodo de 60 segundos entre ejecuciones de la tarea en segundo plano.
Las operaciones de borrado iniciadas por la tarea TTL se ejecutan en primer plano, como otros borrados.
Sets de réplicas
En los nodos del set de réplicas, el hilo de segundo plano de TTL solo borra documentos cuando un nodo está en estado primario. El hilo de segundo plano de TTL está inactivo cuando un nodo está en el estado secundario. Los nodos secundarios replican las operaciones de borrado desde el primario.
Soporte para queries
Un Ãndice TTL brinda soporte a los queries de la misma manera que los Ãndices no TTL.
mongod en modo autónomo
La supervisión de TTL se detiene cuando mongod se ejecuta en modo autónomo y la colección system.local.replset contiene datos.
TTL y validación de esquema
Aunque los Ãndices TTL no requieren validación de esquema, el uso de la validación puede ayudar a garantizar un comportamiento coherente al estandarizar la existencia y el formato del campo de fecha utilizado para la expiración.
Por ejemplo, puedes utilizar la validación de esquema para aplicar la presencia de un campo lastModifiedDate y asegurarse de que su valor cumpla con un formato de fecha válido:
db.createCollection( "eventlog", { validator: { $jsonSchema: { bsonType: "object", required: [ "lastModifiedDate" ], properties: { lastModifiedDate: { bsonType: "date", description: "Must be a valid date." } } } } } )
La validación garantiza:
Cada documento en la colección
eventlogincluye el campolastModifiedDate.El campo
lastModifiedDatecontiene un valor de fecha válido.
Restricciones
Los Ãndices TTL son Ãndices de campo único. Los Ãndices compuestos no brindan soporte a TTL e ignoran la opción
expireAfterSeconds.El campo
_idno brinda soporte a Ãndices TTL.No puedes crear un Ãndice TTL en una colección con tamaño fijo.
A partir de MongoDB 7.0, puedes crear un Ãndice TTL parcial en la colección de series de tiempo
metaField. En versiones anteriores de MongoDB, solo puedes crear un Ãndice TTL para eltimeFieldde una colección de series de tiempo.No puedes usar
createIndex()para cambiar el valor deexpireAfterSecondsde un Ãndice existente. En su lugar, utiliza el comando de base de datoscollMod. Para obtener más detalles, consulta Cambiar el valor deexpireAfterSecondspara un Ãndice TTL.Si ya existe un Ãndice de campo único no TTL para un campo, no puedes crear un Ãndice TTL en el mismo campo porque no se pueden crear Ãndices que tengan la misma especificación de clave y que solo se diferencien por las opciones. Para cambiar un Ãndice de campo único que no sea TTL a un Ãndice TTL, utiliza el comando de base de datos
collMod.