Convert date difference to years to calculate age in MongoDB Convert date difference to years to calculate age in MongoDB mongoose mongoose

Convert date difference to years to calculate age in MongoDB


Update: MongoDB 5.0 solution, will consider leap years as well

db.collection.aggregate([  { $addFields:    { age: { $dateDiff: { startDate: "$dob", endDate: "$$NOW", unit: "year" } } }  }])

Update: We can just combine the aggregation operators. Note that this solution won't give accurate result as it does not consider leap years

db.getCollection('person').aggregate( [ {     $project: {         date:"$demographics.DOB",         age: {             $divide: [{$subtract: [ new Date(), "$Demographics.DOB" ] },                     (365 * 24*60*60*1000)]        }      } } ] )

Old solution with $let


I was able to solve the issue with $let expression

db.getCollection('person').aggregate( [ {     $project: {         item: 1,         date:"$demographics.DOB",         age: {             $let:{                vars:{                    diff: {                         $subtract: [ new Date(), "$demographics.DOB" ]                     }                },                in: {                    $divide: ["$$diff", (365 * 24*60*60*1000)]                }            }        }      } } ] )


The accepted answer is incorrect by as many days as there are a leap years that passed since the person was born. Here's a more correct way to calculate age:

{$subtract:[   {$subtract:[{$year:"$$NOW"},{$year:"$dateOfBirth"}]},   {$cond:[      {$gt:[0, {$subtract:[{$dayOfYear:"$$NOW"},      {$dayOfYear:"$dateOfBirth"}]}]},      1,      0   ]}]}


Starting in Mongo 5.0, it's a perfect use case for the new $dateDiff aggregation operator:

// { "dob" : ISODate("1990-03-27") }// { "dob" : ISODate("2008-08-07") }db.collection.aggregate([  { $addFields:    { age: { $dateDiff: { startDate: "$dob", endDate: "$$NOW", unit: "year" } } }  }])// { "dob" : ISODate("1990-03-27"), "age" : 31 }// { "dob" : ISODate("2008-08-07"), "age" : 13 }

This nicely fits the age scenario since (quoting the documentation) durations produced by $dateDiff are measured by counting the number of times a unit boundary is passed. For example, two dates that are 18 months apart would return 1 year difference instead of 1.5 years.

Also note that $$NOW is a variable that returns the current datetime value.