How to use MongoDB date aggregation operators in Node.js with Mongoose ($dayOfMonth, $dayOfYear, $dayOfWeek, etc)

mongodb

While I was working on creating a tutorial for MongoDB aggregation I came across a few issues while trying to use the built in date aggregation operators.  I was storing the date in the db as the unix epoch timestamp.  I tried multiple variations such as “new Date()”, “new Date().getTime()”, “Date.now()”, etc, but none of those would work.  I kept getting this error “can’t convert from BSON type NumberDouble to Date”.  Turns out, the solution was very simple, and something I completely overlooked

The MongoDB date aggregation operators are designed to work on BSON date/time data type, a 64-bit int storing the number of UTC milliseconds from unix epoch.  In order to use these operators there are a few things you should keep in mind when designing your application and setting everything up.

 

MongoDB Schema Requirements

One thing that I overlooked was the database schema I had already setup.  My original setup in the database schema had the key type set as number…this will not work, and will normally be the cause of why you see the “can’t convert from BSON type NumberDouble to Date” error.

When defining the database schema you must use:

Notice above how we set in the schema to use the Date type instead of Number, String, etc.  You need to use this type as there isn’t any way (at least that I know of) to convert the number to a date inside the MongoDB aggregation framework.  When you set it as a date Type, instead of just storing the value, it will store like this in the MongoDB database:

Instead of:

If you used Number type and set it with epoch milliseconds time, it would be a number instead of date string. Either way, as you can see it is stored in the database as a date object.

 Set and store value using Node.js

Now that the schema has been defined as a Date type it will be stored as a date object, we just need to save it using Node.js like so:

Using MongoDB aggregation date operators (with Mongoose)

Now that we have our Schema set correctly, and stored the date as a date object in the database, we can use any of the MongoDB aggregation date operators as needed:

You can use the date operators inside any of the MongoDB Pipeline Operators. Check out this page for more information:
http://docs.mongodb.org/manual/reference/operator/aggregation/

You’ve now learned how to use the MongoDB Aggregation Date Operators, congrats!

Available MongoDB Aggregation Date Operators

Date operators take a “Date” typed value as a single argument and return
a number.

Name Description
$dayOfYear Converts a date to a number between 1 and 366.
$dayOfMonth Converts a date to a number between 1 and 31.
$dayOfWeek Converts a date to a number between 1 and 7.
$year Converts a date to the full year.
$month Converts a date into a number between 1 and 12.
$week Converts a date into a number between 0 and 53
$hour Converts a date into a number between 0 and 23.
$minute Converts a date into a number between 0 and 59.
$second Converts a date into a number between 0 and 59. May be 60 to account for leap seconds.
$millisecond Returns the millisecond portion of a date as an integer between 0 and 999.

Myles

Orlando, FL

Did this post help you?

Give back and rate it for me!

Related Posts

  • Ryan

    Any way to get a time interval of 15 minutes?

  • uniquate

    Thank you for the article. Any geoNear aggregation example?

    • uniquate

      This aggregation needed for something like skip() with geoNear finding.

    • Don’t have anything yet, but I will try and add something soon and will reply here and let you know.