Sling Academy
Home/Node.js/Mongoose: How to set expire TTL for a document

Mongoose: How to set expire TTL for a document

Last updated: December 30, 2023

In applications involving time-sensitive data, having a mechanism to automatically expire and remove documents can be incredibly useful. In MongoDB, this functionality is provided with TTL (Time To Live) indexes, which can be utilized in Mongoose, a popular MongoDB object modeling tool for Node.js. Here’s a complete guide on how to leverage TTL in your Mongoose schemas for automatic document expiration.

Introduction

Mongoose provides a high-level schema-based solution to model your application data and includes built-in type casting, validation, query building, and business logic hooks. One lesser-known but powerful feature of Mongoose is the ability to set a TTL on documents — a document will be automatically deleted from the collection when the specified Time To Live (TTL) elapses after its creation or a specified timestamp.

This feature is extremely useful for certain types of data that only need to persist for a certain time frame, such as session data or temporary caches. By automatically expiring data, you can reduce the overhead of manually cleaning up old data and ensure that your database does not hold onto unnecessary information indefinitely.

Setting up the Environment

Before diving into the setup, it is assumed that you have Node.js/npm installed and set up on your system. Start by initializing a new Node.js project and installing mongoose:

const express = require('express');
const mongoose = require('mongoose');
const app = express();

mongoose.connect('mongodb://localhost/testdb', {useNewUrlParser: true, useUnifiedTopology: true});

app.listen(3000, () => {
 console.log('Server is running on port 3000');
});

We also need to create a suitable Mongoose Model. In the example, our Schema will be for a collection named Event which will hold documents that should expire after some time.

Basic TTL Setting

A TTL index on a Mongoose schema can be set on a Date type path. It tells MongoDB how long to keep documents in the collection. When the specified time elapses, MongoDB watches and automatically deletes these documents.

const eventSchema = new mongoose.Schema({
 title: String,
 createdAt: { type: Date, default: Date.now, index: {expires: '2h'} }
});

const Event = mongoose.model('Event', eventSchema);

This simple expires option specifies that each document should expire 2 hours after the createdAt field value. Note that the createdAt default value is set to the current server time when a document is created.

In-depth TTL Configuration

Sometimes you need more control over the expiration behavior. You can specify a different Date which becomes the base point from which the TTL is calculated. Mongoose lets you define this pivot dynamically when creating a new Event document or by utilizing schema methods.

eventSchema.methods.setExpiryDate = function(hours) {
 this.createdAt = new Date(Date.now() + hours * 60 * 60 * 1000);
};

const myEvent = new Event({title: 'Special Sale'});
myEvent.setExpiryDate(5);  // This particular event will expire after 5 hours.
myEvent.save();

This flexibility can be especially valuable for applications that require different documents to have various TTLs.

Advanced Usage

There may also be scenarios where an application needs to adjust TTL dynamically or based on some other conditions than the time of document creation. Mongoose’s middleware and query functions provide opportunities for sophisticated control over expiration.

eventSchema.pre('save', function(next) {
 if(this.isNew) {
   this.setExpiryDate(3);  // Set default TTL for new document
 }
 next();
});

eventSchema.methods.extendExpiry = function(extensionHours) {
 const newExpireTime = new Date(this.createdAt.getTime() + extensionHours * 60 * 60 * 1000);
 if (newExpireTime > this.createdAt) {
     this.createdAt = newExpireTime;
     this.save();
 }
};

Here, a save middleware is introduced to provide a default TTL for new documents and extendExpiry method is exposed to alter the expiration point beyond its initial setting programmatically.

Conclusion

Exploiting Mongoose’s flexibility to set document expiration dates with TTL can help manage data more elegantly, increase the efficiency of your database, and keep it clean from old remnants. This tutorial walked you through setting a simple TTL on Mongoose Schema paths and explored more complex setups for controlling time-sensitive data. Using these techniques, you can construct a database strategy that evolves with the necessity of your data’s lifespan.

Next Article: Mongoose: How to push object to an array in a document

Previous Article: Fix: Cannot overwrite model once compiled in Mongoose

Series: Mongoose.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates