Sling Academy
Home/Node.js/Mongoose: How to get the oldest document

Mongoose: How to get the oldest document

Last updated: December 30, 2023

Introduction

When working with MongoDB through Mongoose in a Node.js application, you might come across a situation where you need to fetch the oldest document from a collection. This could be for record-keeping, analytics, or some functionality that relies on the age of the data. Mongoose is a popular ODM (Object Data Modeling) library for MongoDB and Node.js that simplifies interactions with the database by providing a straight-forward API. This tutorial assumes you have a basic understanding of Mongoose and MongoDB, and will guide you through several methods to retrieve the oldest document in a Mongoose model with increasing complexity and utility.

Throughout this tutorial, the latest ES6+ features including arrow functions, async/await, and ES modules will be used. Ensure you have a supported Node.js version installed—version 14.x or higher would work flawatically with the code examples provided.

Basic Find Query

The most straightforward way to get the oldest document is to sort the documents by their creation date and then limit the result to the first document. If you don’t explicitly define a ‘createdAt’ timestamp in your schema, Mongoose automatically adds ‘createdAt’ and ‘updatedAt’ fields to your schema if you enable timestamps:

const mongoose = require('mongoose');
const { Schema } = mongoose;

const yourSchema = new Schema({
  // your schema fields
}, {
  timestamps: true
});

const YourModel = mongoose.model('YourModel', yourSchema);

To find the oldest document, simply use the .find() method, sort by createdAt in ascending order, and then limit the returned documents to just one.

YourModel.find().sort({ createdAt: 1 }).limit(1).then(doc => {
  console.log('The oldest document is:', doc);
}).catch(err => {
  console.error(err);
});

Using Async/Await

With the introduction of async/await syntax in ES7, working with promises, like those returned by Mongoose’s queries, has become much cleaner. Here’s how to fetch the oldest document using async/await:

const getOldestDocument = async () => {
  try {
    const oldestDocument = await YourModel.findOne().sort({ createdAt: 1 });
    console.log('The oldest document is:', oldestDocument);
  } catch (err) {
    console.error('Error finding the oldest document:', err);
  }
};

getOldestDocument();

Working with Custom Timestamps

If your schema defines custom fields for timestamps or you would like to find the oldest document based on a different field altogether, your sort query would change accordingly. Let’s say we want to sort based on a ‘created’ field defined in our schema:

const customSchema = new Schema(
  {
    // other fields...
    created: Date
  }
);

const CustomModel = mongoose.model('CustomModel', customSchema);

const findOldestByCustomDate = async () => { 
  try { 
    const oldestDocument = await CustomModel.findOne().sort({ created: 1 }); 
    console.log('The oldest document by custom date is:', oldestDocument); 
  } catch (err) { 
    console.error('Error finding the oldest document by custom date:', err); 
  } 
};

findOldestByCustomDate();

Optimizing with Lean Queries

When performance is critical and you want to retrieve plain JavaScript objects instead of full Mongoose document instances, you can call the .lean() method on your queries. This is particularly useful when you don’t need the overhead of a full Mongoose model instance:

const readOptimizedOldestDocument = async () => { 
  try { 
    const doc = await YourModel.findOne().sort({ createdAt: 1 }).lean(); 
    console.log('The read-optimized oldest document is:', doc); 
  } catch (err) { 
    console.error('Error reading the optimized oldest document:', err); 
  } 
};

readOptimizedOldestDocument();

Error Handling and Debugging

It’s crucial to handle errors appropriately in your database interaction code. Mongoose provides robust error handling capabilities, and by effectively using try...catch, you can ensure that any exceptions in your query logic are caught. Additionally, when something doesn’t work as expected, Mongoose’s built-in debugging tools can be invaluable. To turn on Mongoose’s debugging mode:

mongoose.set('debug', true);

Doing this will log all MongoDB operations to the console, allowing you to see exactly what Mongoose is sending to the database, which can help you diagnose issues more effectively.

Conclusion

Retrieving the oldest document in a Mongoose model is a fundamentally simple task that can be achieved through various levels of optimization and customization according to your needs. By following this guide, you’ve learned the essential methods for finding documents based on their creation time and making those queries more efficient when necessary. Whether you’re new to MongoDB and Mongoose or an experienced developer, understanding how to manipulate and query your data effectively is crucial, and I hope this article has provided you with the knowledge to do just that.

Next Article: Grouping Results in Mongoose (with examples)

Previous Article: Mongoose: Retrieving the Latest Document

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