How to Compare Date in MongoDB

Tahseen Tauseef Feb 02, 2024
  1. Use Basic Comparison Operators for Date Comparison in MongoDB
  2. Use the $expr Operator for Date Comparison in MongoDB
  3. Use Date Aggregation Functions for Date Comparison in MongoDB
  4. Use $where Operator for Date Comparison in MongoDB
  5. Use Aggregation Pipeline Stages for Date Comparison in MongoDB
  6. Conclusion
How to Compare Date in MongoDB

MongoDB is a popular NoSQL database that provides powerful tools for querying and manipulating data. When working with dates, it’s important to understand how to compare and query them effectively.

In this article, we’ll explore various methods for date comparison in MongoDB, complete with detailed explanations and example codes.

Use Basic Comparison Operators for Date Comparison in MongoDB

MongoDB provides a set of basic comparison operators that can be used for date comparison. Each designed for specific date-related queries, these operators include:

  • $lt: Less than
  • $lte: Less than or equal to
  • $gt: Greater than
  • $gte: Greater than or equal to

Let’s have a sample collection in MongoDB named events with documents containing a startDate field. We will use this collection for our examples below.

db.events.insertMany([
  { name: "Event 1", startDate: ISODate("2023-10-23T10:00:00Z") },
  { name: "Event 2", startDate: ISODate("2023-10-25T15:30:00Z") },
  { name: "Event 3", startDate: ISODate("2023-10-30T09:00:00Z") }
])

Finding Dates After a Specific Date

Suppose you want to retrieve documents with a date later than a particular point in time. The $gt operator comes to your aid.

// Find documents with a date after October 25, 2023
db.collection.find({ dateField: { $gt: ISODate("2023-10-25T00:00:00Z") } })

Here, dateField represents the field containing the date, and ISODate is employed to specify a date in ISO 8601 format. The $gt operator will match documents where dateField is greater than the specified date.

Let’s apply this query to a practical example:

db.events.find({ startDate: { $gt: ISODate("2023-10-25T00:00:00Z") } })

This query will return documents with a date after October 25, 2023.

{
  _id: ObjectId("..."),
  name: 'Event 2',
  startDate: 2023-10-25T15:30:00.000Z
}
{
  _id: ObjectId("..."),
  name: 'Event 3',
  startDate: 2023-10-30T09:00:00.000Z
}

Retrieving Dates On or Before a Specific Date

If your goal is to find documents with dates on or before a particular date, you can utilize the $lte operator.

// Find documents with a date on or before October 25, 2023
db.collection.find({ dateField: { $lte: ISODate("2023-10-25T00:00:00Z") } })

In this example, the $lte operator is used. It matches documents where dateField is less than or equal to the specified date.

Let’s apply this query to a practical example:

db.events.find({ startDate: { $lte: ISODate("2023-10-25T00:00:00Z") } })

This query will return documents with a date on or before October 25, 2023.

{
  _id: ObjectId("..."),
  name: 'Event 1',
  startDate: 2023-10-23T10:00:00.000Z
}

Notice that "Event 2" is not included in the result even though the date is October 25, 2023, because the time of that event is "2023-10-25T15:30:00Z".

Querying for Dates Within a Range

Let’s say you’re interested in retrieving documents with dates within a specific range. A combination of $gte and $lt will serve your purpose.

// Find documents with dates between October 20, 2023 and October 27, 2023
db.collection.find({
  dateField: {
    $gte: ISODate("2023-10-20T00:00:00Z"),
    $lt: ISODate("2023-10-27T00:00:00Z")
  }
})

This query utilizes both $gte and $lt operators to filter documents. It will match documents where dateField is greater than or equal to the start date ($gte) and less than the end date ($lt).

Let’s apply this query to a practical example:

db.events.find({
  startDate: {
    $gte: ISODate("2023-10-20T00:00:00Z"),
    $lt: ISODate("2023-10-27T00:00:00Z")
  }
})

This query will return documents with dates between October 20, 2023 and October 27, 2023.

{
  _id: ObjectId("..."),
  name: 'Event 1',
  startDate: 2023-10-23T10:00:00.000Z
}
{
  _id: ObjectId("..."),
  name: 'Event 2',
  startDate: 2023-10-25T15:30:00.000Z
}

Identifying Dates Before a Specific Date

If your objective is to find documents with dates earlier than a particular date, you can employ the $lt operator.

// Find documents with a date before October 25, 2023
db.collection.find({ dateField: { $lt: ISODate("2023-10-25T00:00:00Z") } })

In this example, the $lt operator is used. It matches documents where dateField is less than the specified date.

Let’s apply this query to a practical example:

db.events.find({ startDate: { $lt: ISODate("2023-10-25T00:00:00Z") } })

This query will return documents with a date before October 25, 2023.

{
  _id: ObjectId("..."),
  name: 'Event 1',
  startDate: 2023-10-23T10:00:00.000Z
}

Use the $expr Operator for Date Comparison in MongoDB

The $expr operator enables the use of aggregation expressions within a query. This means you can leverage the full power of MongoDB’s aggregation framework when performing date comparisons.

It allows for more intricate and customizable queries that may not be achievable with basic comparison operators alone.

The syntax of the $expr operator is as follows:

{ $expr: { <aggregation expression> } }

Here, <aggregation expression> can be any valid aggregation expression. This expression can include aggregation operators, functions, and fields from the documents being queried.

For example, if you want to compare two fields, field1 and field2 using the $expr operator, the syntax would look like this:

db.collection.find({
  $expr: {
    $eq: [ "$field1", "$field2" ]
  }
})

In this example, we’re using the $eq operator inside the $expr expression to check if the values of field1 and field2 are equal.

Keep in mind that the $expr operator is particularly useful when you need to perform comparisons or operations that the standard query operators do not directly support. It allows you to leverage the full power of MongoDB’s aggregation framework within your queries.

Here’s a complete code example demonstrating the usage of the $expr operator for date comparison in MongoDB. Suppose we have a collection named events with documents containing two date fields, start_date and end_date.

// Insert sample documents into the 'events' collection
db.events.insertMany([
  {
    name: "Event 1",
    start_date: ISODate("2023-10-25T08:00:00Z"),
    end_date: ISODate("2023-11-27T20:00:00Z")
  },
  {
    name: "Event 2",
    start_date: ISODate("2023-11-01T10:00:00Z"),
    end_date: ISODate("2023-11-03T18:00:00Z")
  },
  {
    name: "Event 3",
    start_date: ISODate("2023-11-05T12:00:00Z"),
    end_date: ISODate("2023-11-08T14:00:00Z")
  }
])

Now, let’s use the $expr operator to find events with a duration longer than 7 days.

// Find events with a duration longer than 7 days
db.events.find({
  $expr: {
    $gt: [
      { $subtract: ["$end_date", "$start_date"] },
      7 * 24 * 60 * 60 * 1000  // 7 days in milliseconds
    ]
  }
})

In this example, we first insert sample documents into the events collection. Then, we use the $expr operator in the find method to perform the date comparison.

We calculate the difference in milliseconds between end_date and start_date using the $subtract operator. We then compare this difference to the equivalent of 7 days in milliseconds using the $gt operator.

The results will be events that have a duration longer than 7 days. The output will display the details of these events.

{
  _id: ObjectId("..."),
  name: 'Event 1',
  start_date: 2023-10-25T08:00:00.000Z,
  end_date: 2023-11-27T20:00:00.000Z
}

This code example showcases how to use the $expr operator for date comparison in MongoDB, specifically for finding events with a duration longer than a specified threshold.

Use Date Aggregation Functions for Date Comparison in MongoDB

Date aggregation functions in MongoDB allow for advanced date manipulation within queries. These functions enable you to extract specific components of dates (like year, month, etc.) and perform calculations involving dates.

Let’s start with some basic examples to get a grasp of how date aggregation functions work.

Example 1: Extracting the Year

Suppose we have a collection named events with documents containing a start_date field. We want to find events that occurred in the year 2023.

db.events.aggregate([
  {
    $project: {
      year: { $year: "$start_date" }
    }
  },
  {
    $match: {
      year: 2023
    }
  }
])

In this example, we use the $year aggregation function to extract the year from the start_date. We then use $project to add a new field called year to each document. Finally, we use $match to filter documents where year is equal to 2023.

Output:

{
  _id: ObjectId("..."),
  year: 2023
}
{
  _id: ObjectId("..."),
  year: 2023
}
{
  _id: ObjectId("..."),
  year: 2023
}

Example 2: Calculating the Difference in Days

Suppose we want to find events that have a duration longer than 7 days.

db.events.aggregate([
  {
    $addFields: {
      durationInDays: {
        $divide: [
          { $subtract: ["$end_date", "$start_date"] },
          24 * 60 * 60 * 1000  // Convert milliseconds to days
        ]
      }
    }
  },
  {
    $match: {
      durationInDays: { $gt: 7 }
    }
  }
])

In this example, we use the $subtract operator to find the difference in milliseconds between end_date and start_date. We then use $divide to convert this difference to days.

The result is stored in a new field called durationInDays. Finally, we use $match to filter events with a duration greater than 7 days.

Output:

{
  _id: ObjectId("..."),
  name: 'Event 1',
  start_date: 2023-10-25T08:00:00.000Z,
  end_date: 2023-11-27T20:00:00.000Z,
  durationInDays: 33.5
}

Advanced Usage of Date Aggregation Functions

Let’s now explore more advanced scenarios using date aggregation functions.

Example 3: Finding Events in the Current Month

Suppose we want to find events that are scheduled for the current month.

var today = new Date();
var startOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
var endOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);

db.events.find({
  start_date: {
    $gte: startOfMonth,
    $lte: endOfMonth
  }
})

In this example, we use JavaScript to calculate the first day (startOfMonth) and last day (endOfMonth) of the current month. We then use these dates in a query to find events that fall within this range.

Output:

{
  _id: ObjectId("..."),
  name: 'Event 1',
  start_date: 2023-10-25T08:00:00.000Z,
  end_date: 2023-11-27T20:00:00.000Z
}

Use $where Operator for Date Comparison in MongoDB

The $where operator in MongoDB allows you to execute JavaScript functions for each document in a collection. This provides a high degree of flexibility, allowing you to perform complex date comparisons and other operations that may not be easily achievable using standard query operators.

Basic Usage

Let’s start with a basic example to illustrate how the $where operator works for date comparison.

Suppose we have a collection named events with documents containing two date fields, start_date and end_date. We want to find events that have already ended.

db.events.find({
  $where: function() {
    return this.end_date < new Date();
  }
})

In this example, we use the $where operator to execute a JavaScript function for each document. Inside the function, this refers to the current document.

We compare the end_date of the event with the current date (new Date()) and return true if the event has already ended.

Advanced Usage

Now, let’s explore some advanced scenarios using the $where operator.

Example 1: Comparing Dates with Specific Values

Suppose we want to find events that occurred in the year 2023.

db.events.find({
  $where: function() {
    return this.start_date.getFullYear() === 2023;
  }
})

In this example, we use the $where operator to execute a JavaScript function. Inside the function, we use the getFullYear() method to get the year of start_date. We then compare it to 2023 and return true if they match.

Example 2: Complex Date Comparisons

Suppose we want to find events where the duration is longer than 3 days.

db.events.find({
  $where: function() {
    var durationInMilliseconds = this.end_date - this.start_date;
    var durationInDays = durationInMilliseconds / (1000 * 60 * 60 * 24);
    return durationInDays > 3;
  }
})

In this example, we calculate the duration of the event in days by finding the difference in milliseconds between end_date and start_date. We then compare this duration to 3 days and return true if it’s greater.

Use Aggregation Pipeline Stages for Date Comparison in MongoDB

The aggregation pipeline in MongoDB allows for a series of data processing operations to be applied in sequence. Each stage performs a specific operation on the documents that pass through it. This makes it a powerful tool for complex data manipulation tasks, including date comparison.

Basic Usage of Aggregation Pipeline for Date Comparison

Let’s start with some basic examples to demonstrate how aggregation pipeline stages can be used for date comparison.

Example 1: Finding Events in a Date Range

Suppose we have a collection named events with documents containing a start_date and end_date field. We want to find events that occurred between two specific dates.

var startDate = ISODate("2023-10-25T00:00:00Z");
var endDate = ISODate("2023-11-01T00:00:00Z");

db.events.aggregate([
  {
    $match: {
      start_date: { $gte: startDate },
      end_date: { $lt: endDate }
    }
  }
])

In this example, we use the $match stage to filter events based on the specified date range. The $gte and $lt operators are used to check if the start_date is greater than or equal to the startDate and if the end_date is less than the endDate.

Example 2: Calculating Event Durations

Suppose we want to calculate the duration of each event in hours.

db.events.aggregate([
  {
    $addFields: {
      durationInHours: {
        $divide: [
          { $subtract: ["$end_date", "$start_date"] },
          60 * 60 * 1000  // Convert milliseconds to hours
        ]
      }
    }
  }
])

In this example, we use the $subtract operator to find the difference in milliseconds between end_date and start_date. We then use $divide to convert this difference to hours. The result is stored in a new field called durationInHours using $addFields.

Advanced Usage of Aggregation Pipeline for Date Comparison

Now, let’s explore more advanced scenarios using the aggregation pipeline stages.

Example 3: Grouping Events by Month

Suppose we want to group events by the month of their start_date and calculate the average duration for each month.

db.events.aggregate([
  {
    $group: {
      _id: { $month: "$start_date" },
      averageDuration: { $avg: { $subtract: ["$end_date", "$start_date"] } }
    }
  }
])

In this example, we use the $group stage to group events by the month extracted from start_date using the $month aggregation function. We then calculate the average duration for each group by subtracting start_date from end_date and using the $avg operator.

Output:

{
  _id: 10,
  averageDuration: 2851200000
}
{
  _id: 11,
  averageDuration: 234000000
}

Conclusion

In this guide, we’ve covered various methods for date comparison in MongoDB.

  1. Basic Operators: We explored using $lt, $lte, $gt, and $gte to filter dates effectively.
  2. $expr Operator: This advanced operator leverages MongoDB’s aggregation framework for intricate date comparisons.
  3. Date Aggregation Functions: These functions enable precise date manipulation within queries, like extracting the year or calculating durations.
  4. $where Operator: It executes JavaScript functions for each document, allowing for complex date comparisons and operations.
  5. Aggregation Pipeline: This feature applies a sequence of operations for powerful data manipulation, including date-based comparisons.

With these techniques, you have a versatile toolkit to handle a wide range of date-related queries in MongoDB, ensuring you can extract valuable insights from your data efficiently.

Related Article - MongoDB Date