MongoDB – Working with Date and Time


Overview

One of the most common pain points in querying mongodb is datetime operations. Even if you know the query operators, typing the query will raise doubts. In this blog I will try to help you out on date queries in MongoDB.

MongoDB Query Example (less than)

Assume that you have the following record stored in MongoDB Collection and you like to query those records and get records which are less than 22 Feb 2022. See the below document for record stored in DB

_id:6213291e5abd9c9b33c50ad5
StudentId:1
Name:"Pallav Lalitv"
EnrolmentDate:2022-02-01T00:00:00.000+00:00
_id:621329925abd9c9b33c50ad6

StudentId:2
Name:"Rohan Niraj"
EnrolmentDate:2022-01-01T00:00:00.000+00:00
_id:621329b35abd9c9b33c50ad7

StudentId:3
Name:"Aswathi Savitri"
EnrolmentDate:2022-03-01T00:00:00.000+00:00

We are going to use ISODate Attribute for Querying records, This will allow query to use any standard comparison operator (e.g., =, >, <, !=) for date search.

Query MongoDB ISODate Attribute

Get record of date less than “2022-02-02T08:30.00.000Z”

Using ISODate syntax ( Table: DB.students )

{
     "EnrolmentDate" : {
         "$lt" : new ISODate("2022-02-02T08:30:00.000Z")
     }
}

Output:

_id:6213291e5abd9c9b33c50ad5
StudentId:1
Name:"Pallav Lalitv"
EnrolmentDate:2022-02-01T00:00:00.000+00:00
_id:621329925abd9c9b33c50ad6

StudentId:2
Name:"Rohan Niraj"
EnrolmentDate:2022-01-01T00:00:00.000+00:00

Other Operations are below as per MongoDB Doc

NameDescription
$eqMatches values that are equal to a specified value.
$gtMatches values that are greater than a specified value.
$gteMatches values that are greater than or equal to a specified value.
$inMatches any of the values specified in an array.
$ltMatches values that are less than a specified value.
$lteMatches values that are less than or equal to a specified value.
$neMatches all values that are not equal to a specified value.
$ninMatches none of the values specified in an array.

Date Already Stored as String

If the date is already stored in string format

Records

_id:6213291e5abd9c9b33c50ad5
StudentId:1
Name:"Pallav Lalitv"
EnrolmentDate:"2022-02-01T00:00:00.000Z"
 
_id:621329925abd9c9b33c50ad6
StudentId:2
Name:"Rohan Niraj"
EnrolmentDate:"2022-01-01T00:00:00.000Z"

_id:621329b35abd9c9b33c50ad7
StudentId:3
Name:"Aswathi Savitri"
EnrolmentDate:"2022-03-01T00:00:00.000Z"

For operation on date which is stored in string format in mongoDB we can use `$dateFromString` in an aggregate query.

( Table: DB.students )

$project

{
  StudentId: 1,
  Name: 1,
  EnrolmentDate: { $dateFromString: {
    dateString: "$EnrolmentDate",
    format: "%Y-%m-%dT%H:%M:%S.%LZ"
  }}
}

$match

{
  "EnrolmentDate": {
   "$lt" : new Date("2022-02-01T00:00:00.000Z")
  }
}

MongoDB Query Example (Between Dates)

Suppose we need records of students who are enrolled in January month.

Using ISODate syntax ( Table: DB.students ) – In January 2022

{
      "EnrolmentDate": {
           "$gte" : new Date("2022-01-01T00:00:00.000Z"),
           "$lt" : new Date("2022-02-01T00:00:00.000Z")
      }
}

MongoDB Query Example (Only Dates)

Suppose we need records of students who are enrolled on 5th January 2022.

In this we only need date comparison no time comparison required

Using ISODate syntax ( Table: DB.students )

{
      "EnrolmentDate": {
           "$eq" : new Date("2022-01-05"),
      }
}

MongoDB Query Example (Past/Future Date)

Suppose we need records of students who are enrolled before 30 days or before that. The time difference needs to be give in milliseconds

Using ISODate syntax ( Table: DB.students ) – 30 days before

{
      "EnrolmentDate": {
           "$lt" : new Date(ISODate().getTime() - 1000 * 60 * 60 * 24 * 30)
      }
}

Same way we can use for (seconds, minutes & hours):

  • No Of Seconds : 1000 * seconds
  • No Of Minutes : 1000 * 60 * minutes
  • No Of Hours : 1000 * 60 * 60 * hours
  • No Of Days : 1000 * 60 * 60 * 24 * days

Examples that might be helpful

After 30 Days

{ "EnrolmentDate": { "$gt": new Date(ISODate().getTime() + 1000 * 60 * 60 * 24 * 30)}}

Before 16 hours

{ "EnrolmentDate": { "$lt": new Date(ISODate().getTime() - 1000 * 60 * 60 * 16)}}

After 15 hours

{ "EnrolmentDate": { "$gt": new Date(ISODate().getTime() + 1000 * 60 * 60 * 15)}}

Before 32 Minutes

{ "EnrolmentDate": { "$lt": new Date(ISODate().getTime() - 1000 * 60 * 32)}}

After 16 Minutes

{ "EnrolmentDate": { "$gt": new Date(ISODate().getTime() + 1000 * 60 * 16)}}

Before 45 Seconds

{ "EnrolmentDate": { "$lt": new Date(ISODate().getTime() - 1000 * 60 * 45)}}

After 15 Seconds

{ "EnrolmentDate": { "$gt": new Date(ISODate().getTime() + 1000 * 60 * 15)}}

Leave A Comment

Your email address will not be published. Required fields are marked *