Auto Delete Expired Documents in MongoDB with Node.js (TTL Index)
TTL Indexes in MongoDB are very useful for storing data like logs or user sessions. The document will remove itself after a certain amount of time which is specified by the index. This tutorial will be done in both JavaScript and TypeScript using Node.js with node-mongodb-native
, which is the official MongoDB Node.js driver.
Install MongoDB Node.js Driver
Install node-mongodb-native
from NPM:
$ npm i mongodb
Connect to MongoDB
Connect to the MongoDB server and select the database:
-
JavaScript
const MongoClient = require('mongodb').MongoClient; async function init() { const Client = await MongoClient.connect('mongodb://127.0.0.1:27017'); // change it to the address your MongoDB is listening on const Database = Client.db('MyDatabase'); // change it to the database name of your choice }
Javascript -
TypeScript
import { MongoClient } from 'mongodb'; async function init() { const Client = await MongoClient.connect('mongodb://127.0.0.1:27017'); // change it to the address your MongoDB is listening on const Database = Client.db('MyDatabase'); // change it to the database name of your choice }
TypeScript
Make sure the MongoDB daemon is up and running in the background while connecting.
Create/Select Collection
Select a collection, it'll create itself if it does not exist:
-
JavaScript
... async function init() { ... const Collection = Database.collection('MyCollection'); // change it to the collection name of your choice }
Javascript -
TypeScript
... interface Collection_MyCollection { date: Date; msg: string; } // create a interface specifying the type of the document async function init() { ... const Collection = Database.collection<Collection_MyCollection>('MyCollection'); // change it to the collection name of your choice }
TypeScript
Create TTL (Time-To-Live) Index
Create a TTL index on the collection:
...
async function init() {
...
await Collection.createIndex({
date: 1, // 1 for ascending, -1 for descending
}, {
expireAfterSeconds: 60 * 60 * 24, // expire after 24 hours
}); // documents will expire after 24 hours relative to the field `date`
}
Javascript
The field you specify should be in type
Date
, otherwise it won't work.
Try It Out
We'll create a function called printDocuments
to print out the documents in the collection, and insert two documents with the current date and day before to see if they expire correctly:
...
async function init() {
...
async function printDocuments() {
console.log(await Collection.find({}).toArray()); // print all documents in the collection
}
await Collection.insertOne({
date: new Date(), // today
msg: 'this won\'t expire soon',
});
await Collection.insertOne({
date: new Date(Date.now() - 60 * 60 * 24 * 1000), // yesterday
msg: 'this will expire soon',
});
printDocuments();
setTimeout(() => {
printDocuments();
}, 60 * 2 * 1000); // since MongoDB only performs deletion every 60 seconds, we'll check the documents after 2 minutes
}
init(); // execute the function
Javascript
[
{
_id: new ObjectId("6203411f91c0d03dffa77509"),
date: 2022-02-09T04:20:47.313Z,
msg: "this won't expire soon"
},
{
_id: new ObjectId("6203411f91c0d03dffa7750a"),
date: 2022-02-08T04:20:47.317Z,
msg: 'this will expire soon'
}
]
Output
[
{
_id: new ObjectId("6203411f91c0d03dffa77509"),
date: 2022-02-09T04:20:47.313Z,
msg: "this won't expire soon"
}
]
Output
Be aware that MongoDB runs the background task that removes expired documents every 60 seconds, so there will be a short period of delay before the expired documents get deleted.
If the document didn't get deleted, verify the index is created correctly:
Full Example
A full example including above steps:
-
JavaScript
const MongoClient = require('mongodb').MongoClient; async function init() { const Client = await MongoClient.connect('mongodb://127.0.0.1:27017'); const Database = Client.db('MyDatabase'); const Collection = Database.collection('MyCollection'); await Collection.createIndex({ date: 1, }, { expireAfterSeconds: 60 * 60 * 24, }); async function printDocuments() { console.log(await Collection.find({}).toArray()); } await Collection.insertOne({ date: new Date(), msg: 'this won\'t expire soon', }); await Collection.insertOne({ date: new Date(Date.now() - 60 * 60 * 24 * 1000), msg: 'this will expire soon', }); printDocuments(); setTimeout(() => { printDocuments(); }, 60 * 2 * 1000); } init();
Javascript -
TypeScript
import { MongoClient } from 'mongodb'; interface Collection_MyCollection { date: Date; msg: string; } async function init() { const Client = await MongoClient.connect('mongodb://127.0.0.1:27017'); const Database = Client.db('MyDatabase'); const Collection = Database.collection<Collection_MyCollection>('MyCollection'); await Collection.createIndex({ date: 1, }, { expireAfterSeconds: 60 * 60 * 24, }); async function printDocuments() { console.log(await Collection.find({}).toArray()); } await Collection.insertOne({ date: new Date(), msg: 'this won\'t expire soon', }); await Collection.insertOne({ date: new Date(Date.now() - 60 * 60 * 24 * 1000), msg: 'this will expire soon', }); printDocuments(); setTimeout(() => { printDocuments(); }, 60 * 2 * 1000); } init();
TypeScript