Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I filter an ISODate field based only the in the time in MongoDB

I have a collection with the following structure in MongoDB:

    {
      "Name": "Test",
      "StartDatetime": ISODate('2024-05-15T15:00:41.180+00:00'),
      "EndDatetime": ISODate('2024-05-15T15:30:12.120+00:00')
    }

I have many records in this collection with different datetimes, and I want to filter them based solely on the time, ignoring the date. For example, I want to retrieve all documents where the time is between 02:32:05 and 05:23:12.

I wrote this query:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

db.collection.find({
  $expr: {
    $and: [
      {
        $or: [
          {
            $gte: [
              {
                $concat: [
                  { $substr: [{ $hour: "$StartDateTime" }, 0, 2] },
                  ":",
                  { $substr: [{ $minute: "$StartDateTime" }, 0, 2] },
                  ":",
                  { $substr: [{ $second: "$StartDateTime" }, 0, 2] }
                ]
              },
              "02:32:05"
            ]
          },
          {
            $and: [
              { $eq: [{ $hour: "$StartDateTime" }, 2] },
              { $gte: [{ $concat: [{ $substr: [{ $minute: "$StartDateTime" }, 0, 2] }, ":", { $substr: [{ $second: "$StartDateTime" }, 0, 2] }] }, "32:05"] }
            ]
          }
        ]
      },
      {
        $or: [
          {
            $lte: [
              {
                $concat: [
                  { $substr: [{ $hour: "$EndDateTime" }, 0, 2] },
                  ":",
                  { $substr: [{ $minute: "$EndDateTime" }, 0, 2] },
                  ":",
                  { $substr: [{ $second: "$EndDateTime" }, 0, 2] }
                ]
              },
              "05:23:12"
            ]
          },
          {
            $and: [
              { $eq: [{ $hour: "$EndDateTime" }, 5] },
              { $lte: [{ $concat: [{ $substr: [{ $minute: "$EndDateTime" }, 0, 2] }, ":", { $substr: [{ $second: "$EndDateTime" }, 0, 2] }] }, "23:12"] }
            ]
          }
        ]
      }
    ]
  }
})

However it is not working and I also believe there might be a better way to write this query. I have searched online, but I only found answers about how to create a query based solely on the date.

>Solution :

Currently, it is unclear about your date comparing logic as provided in your example. However, the idea is to convert the date fields into strings using $dateToString that match your input date format (i.e. %H:%m:%S). Then, perform strings comparison for the strings.

db.collection.aggregate([
  {
    "$match": {
      "$expr": {
        "$and": [
          {
            "$gte": [
              {
                "$dateToString": {
                  "date": "$StartDatetime",
                  "format": "%H:%m:%S"
                }
              },
              "02:32:05"// your start date input here
              
            ]
          },
          {
            "$lt": [
              {
                "$dateToString": {
                  "date": "$EndDatetime",
                  "format": "%H:%m:%S"
                }
              },
              "05:23:12"// your end date input here
              
            ]
          }
        ]
      }
    }
  }
])

Mongo Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading