Expirar dados de coleções definindo TTL
Nesta página
Este documento fornece uma introdução ao recurso "time to live" ou de coleçãoTTL do MongoDB. As coleções TTL permitem armazenar dados no MongoDB e fazer com que o mongod
remova automaticamente os dados após um número especificado de segundos ou em um horário específico.
Você pode expirar dados para instalações hospedadas nos seguintes ambientes:
MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
A expiração de dados é útil para algumas classes de informações, incluindo dados de eventos gerados por máquina, logs e informações de sessão que só precisam persistir por um período limitado de tempo.
Uma propriedade de índice TTL especial suporta a implementação de coleções TTL. O recurso TTL depende de um thread em segundo plano no mongod
que lê os valores digitados por data no índice e remove documentos expirados da coleção.
Para criar um índice TTL, utilize createIndex()
. Especifique um campo de índice que seja um tipo de data ou uma matriz que contenha valores de tipo de data. Use a opção expireAfterSeconds
para especificar um valor de TTL em segundos.
Observação
O índice TTL é um índice de campo único. Os índices compostos não suportam a propriedade TTL. Para obter mais informações sobre índices TTL, consulte Índices TTL.
Você pode modificar o expireAfterSeconds
de um índice TTL existente utilizando o comando collMod
.
Se uma coleção de séries temporais contiver documentos com timeField
registros de data e hora anteriores a 1970-01-01T00:00:00.000Z
ou posteriores a 2038-01-19T03:14:07.000Z
, nenhum documento será excluído da coleção pelo recurso TTL "time to live".
Expirar documentos na interface do usuário do Atlas MongoDB
Para expirar dados na IU do Atlas, siga estas etapas:
Na interface do usuário do MongoDB Atlas, acesse a página Clusters do seu projeto.
Se ainda não tiver sido exibido, selecione a organização que contém seu projeto no menu Organizations na barra de navegação.
Se ainda não estiver exibido, selecione seu projeto no menu Projects na barra de navegação.
Se ainda não estiver exibido, clique em Clusters na barra lateral.
A página Clusters é exibida.
Crie o índice com a opção expiresAfterSeconds
Na seção Fields, insira o documento de especificação da chave de índice. Para este exemplo, insira o seguinte texto para criar um índice no campo
expiresAfter
:{ "expiresAfter": 1 } Na seção Options, insira a opção
expireAfterSeconds
. Para este exemplo, insira o seguinte texto para expirar os dados 1 segundo após o valor do campoexpiresAfter
:{ expireAfterSeconds: 1 } Clique em Review.
Clique em Confirm.
Adicione um documento que contenha o campo expiresAfter
à coleção
No painel de navegação à esquerda, selecione a collection que contém o índice.
Clique na aba Find.
Clique em Insert Document.
Clique no campo de texto abaixo do campo _id e insira o nome do campo
expiresAfter
.Clique no campo de texto ao lado de
expiresAfter
e introduza o seguinte valor:2023-10-01T12:00:00.000+00:00 Esse valor expira dados após as 12:00 de 1 de outubro de 2023.
Clique no menu suspenso do tipo de dados e altere o valor do tipo de dados para Date.
Clique em Insert.
O documento expirará automaticamente um segundo após o valor do campo
expiredAfter
.O índice TTL pode levar de 1 a 2 segundos para expirar o documento. Talvez seja necessário atualizar a UI para ver que o MongoDB Atlas exclui o documento expirado.
Expirar documentos após um número especificado de segundos
Você pode expirar os dados após um número específico de segundos no terminal. Para expirar os dados depois que um número especificado de segundos tiver passado desde o campo indexado, crie um índice TTL em um campo que contenha valores do tipo data BSON ou uma array de objetos do tipo data BSON e especifique um valor positivo diferente de zero no campo expireAfterSeconds
. Um documento expirará quando o número de segundos no campo expireAfterSeconds
tiver passado desde o tempo especificado em seu campo indexado. [1]
O valor expireAfterSeconds
do índice TTL deve estar dentro de 0
e 2147483647
inclusive.
Por exemplo, a seguinte operação cria um índice no campo log_events
da collection createdAt
e especifica o valor expireAfterSeconds
de 10
para definir o tempo de expiração para dez segundos após o tempo especificado por createdAt
.
db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 10 } )
Ao adicionar documentos à coleção log_events
, defina o campo createdAt
para o horário atual:
db.log_events.insertOne( { "createdAt": new Date(), "logEvent": 2, "logMessage": "Success!" } )
O MongoDB excluirá automaticamente os documentos da coleção log_events
quando o valor createdAt
do documento [1] for maior que o número de segundos especificado em expireAfterSeconds
.
[1] | (1, 2) Se o campo contiver uma array de objetos do tipo data BSON, os dados expiram se pelo menos um dos objetos do tipo data do BSON for mais antigo do que o número de segundos especificado em expireAfterSeconds . |
Expirar documentos com condições de filtro
Para expirar documentos com expressões de filtro específicas, você pode criar um índice que seja tanto um índice parcial quanto um índice TTL.
Criar um índice TTL parcial:
db.foo.createIndex( { F: 1 }, { name: "Partial-TTL-Index", partialFilterExpression: { D : 1 }, expireAfterSeconds: 10 } )
Insira dois documentos, um dos quais corresponde à expressão de filtro { D : 1 }
do partialFilterExpression
:
db.foo.insertMany( [ { "F" : ISODate("2019-03-07T20:59:18.428Z"), "D" : 3}, { "F" : ISODate("2019-03-07T20:59:18.428Z"), "D" : 1} ] )
Aguarde dez segundos e faça a query da collection foo
:
db.foo.find({}, {_id: 0, F: 1, D: 1})
O documento que corresponde a partialFilterExpression
de { D : 1 }
foi excluído (expirado). Como resultado, apenas um documento permanece na coleção foo
:
{ "F" : ISODate("2019-03-07T20:59:18.428Z"), "D" : 3}
Expirar documentos em um horário específico
Você pode expirar os dados em um tempo de relógio especificado no terminal. Para expirar documentos em um horário de relógio específico, comece criando um índice TTL em um campo que contenha valores do tipo de data BSON ou uma matriz de objetos do tipo data BSON e especifique um valor expireAfterSeconds
de 0
. Para cada documento na coleção, defina o campo de data indexada como um valor correspondente à hora em que o documento deve expirar. Se o campo de data indexada contiver uma data no passado, MongoDB considera o documento expirado.
Por exemplo, a seguinte operação cria um índice no campo log_events
da coleção expireAt
e especifica o valor expireAfterSeconds
de 0
:
db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
Para cada documento, defina o valor de expireAt
para corresponder à hora em que o documento deve expirar. Por exemplo, a operação insertOne()
a seguir adiciona um documento que expira em July 22, 2013 14:00:00
.
db.log_events.insertOne( { "expireAt": new Date('July 22, 2013 14:00:00'), "logEvent": 2, "logMessage": "Success!" } )
O MongoDB excluirá automaticamente os documentos da collection log_events
quando o valor expireAt
dos documentos for mais antigo do que o número de segundos especificado em expireAfterSeconds
, ou seja, 0
segundos mais antigo neste caso. Dessa forma, os dados expiram no valor expireAt
especificado.
Índices configurados usando NaN
Aviso
Possível perda de dados
Quando um índice TTL tem expireAfterSeconds
definido para NaN
, a atualização, o downgrade e determinadas operações de sincronização podem levar a um comportamento inesperado e possível perda de dados.
Não defina expireAfterSeconds
como NaN
na configuração do índice TTL.
Antes do MongoDB 5.0, quando um índice TTL tem expireAfterSeconds
definido como NaN
, o MongoDB registra um erro e não remove nenhum registro.
Do MongoDB 5.0.0 - 5.0.13 (e 6.0.0 - 6.0.1), NaN
é tratado como 0
. Se um índice TTL for configurado com expireAfterSeconds
definido como NaN
, todos os documentos indexados em TTL expirarão imediatamente.
Iniciando no MongoDB 5.0.14 (e 6.0.2), o servidor não utilizará índices TTL que tenham expireAfterSeconds
definido como NaN
.
No entanto, ainda há algumas situações que podem resultar em comportamento inesperado. Os documentos podem expirar:
Durante uma sincronização inicial com uma versão anterior do MongoDB 5.0.0 - 5.0.13 (ou 6.0.0 - 6.0.1).
Ao atualizar de uma versão anterior para MongoDB 5.0.0 - 5.0.13.
Ao restaurar uma coleção de um pré-5.0
mongodump
em um MongoDB 5.0.0 - 5.0.13 (ou 6.0.0 - 6.0.1) instância.
Para evitar problemas, deixe cair ou corrija quaisquer índices de TTL configurados incorretamente.
Identifique índices mal configurados.
Execute o seguinte roteiro no shell mongosh
. O roteiro não funciona no shell mongo
legado.
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();
Corrija índices mal configurados.
Utilize o comando collMod
para atualizar quaisquer valores de expireAfterSeconds
mal configurados que o script encontrou.
Como alternativa, você pode drop
quaisquer índices TTL configurados incorretamente e recriá-los posteriormente usando o comando createIndexes
.