00:00 / 00:00

Fecha publicación: 28 jun 2021

MongoDb Time To Leave Indexes

¿Recuerdas esa típica escena de las películas de espías en las que el protagonista leía el mensaje secreto explicando su misión y se oía una grabación que decía "este mensaje se autodestruirá en 10 segundos"? ... pues de eso vamos a hablar hoy pero, con MongoDb ;).

Inspector Gadget este mensaje se autodestruirá

Hay situaciones en las que cuando insertamos documentos en una colección no queremos que perduren para siempre, por ejemplo si tratamos con datos de una sesión de usuario, o cachés, u otros elementos temporales.

¿Cómo solíamos tratar esta casuística con otros motores de base de datos relacionales?

  • O bien haciendo procesos manuales de limpia cada X tiempo.
  • O bien teniendo demonios o triggers que se disparan cada X tiempo.

¿Cómo podemos hacer esto con MongoDb? Utilizando los Time To Leave Indexes, también conocidos como índices TTL: la forma que tienen de funcionar es muy interesante, tu le añades a cada documento un campo fecha en el que le indicas cuando se creó el mismo, y después creas un índice en el que sobre ese campo fecha (timestamp), le das un tiempo de expiración en segundos (60 segundos, 1 hora, 48 horas... lo que mejor te venga).

Manos a la obra

Veamos como funciona esto con un ejemplo, nos vamos al terminal y nos ponemos a interactuar con el cli de mongo.

mongo

Vamos a crear una base de datos de prueba:

use miprueba

Vamos a crear una colección que llamaremos sesiones

db.createCollection('sesiones');

Definimos un Time To Leave Index, y le indicamos al motor de mongo que esa colección va a tener un campo que lo llamaremos fechaCreacion y que periódicamente, chequee y borre los documentos que hayan expirado, es decir borrar si: fecha hora actual < fechaCreación + 10 segundos.

db.sesiones.createIndex({ fechaCreacion: 1 }, { expireAfterSeconds: 10 });

Vamos a probar que esto funciona, insertamos una entrada, y utilizando new Date() le indicamos que en fechaCreacion guarde la fecha y hora actual.

db.sesiones.insert({
  fechaCreacion: new Date(),
  datos: "Prueba de contenido A",
});

Si le echamos un ojo rápido, podemos ver que el documento sigue existiendo:

db.sesiones.find({});

Si esperamos justo los 10 segundos y ejecutamos otra vez la consulta puede ser que sigamos viendo el documento, ¿qué pasa aquí? MongoDb lanza cada 60 segundos un proceso interno que es el que recorre los índices TTL y se pone a borrar los documentos que hayan caducado, además, esto también puede tardar un poco más dependiendo de la carga que tenga el servidor en ese momento, esto no suele ser problema ya que lo normal es que manejemos tiempos de expiración más elevados (por ejemplo una sesión suele durar mínimo 30 minutos).

Vamos a probar si Mongo ha hecho su trabajo, volvemos a ejecutar el find y vemos que ya el documento no esta:

db.sesiones.find({});

Si te animas, puedes poner un tiempo de expiración más elevado y probar a insertar elementos en diferentes tiempos y comprobar como unos documentos se van borrando y otros se quedan dependiendo del timestamp que tenga cada campo fecha.

Curiosidad

Como curiosidad, otra forma interesante de gestionar la expiración en los indices TTL es crearlos con un tiempo de expiración de 0 segundos y directamente estableciendo en cada documento la fecha de expiración a futuro, así cuando se llegue a dicha fecha/hora el demonio de MongoDb lo eliminará.

¿Con ganas de aprender Backend?

En Lemoncode impartimos un Bootcamp Backend Online, centrado en stack node y stack .net, en él encontrarás todos los recursos necesarios: clases de los mejores profesionales del sector, tutorías en cuanto las necesites y ejercicios para desarrollar lo aprendido en los distintos módulos. Si quieres saber más puedes pinchar aquí para más información sobre este Bootcamp Backend.