Mongol aggregation structure: group users by age

I have a user base stored in mongo. Users can record their date of birth. I need to run a report uniting users by age .

Now I have a pipeline that groups users by year of birth. However, this is not accurate enough because most people were not born on January 1; so even if they were born, say, in 1970, there may well be 43 of them.

db.Users.aggregate([ { $match : { "DateOfBirth" : { $exists : true} } }, { $project : {"YearOfBirth" : {$year : "$DateOfBirth"} } }, { $group : { _id : "$YearOfBirth", Total : { $sum : 1} } }, { $sort : { "Total" : -1 } } ]) 

Do you know if it is possible to perform any arithmetic within the framework of aggregation in order to accurately calculate the age of the user? Or is this only possible with MapReduce?

+6
source share
2 answers

Everything seems to be possible with the released new version of Mongo 2.4, which supports additional Date operations (namely, "subtracting $").

Here is how I did it:

 db.Users.aggregate([ { $match : { "DateOfBirth" : { $exists : true} } }, { $project : {"ageInMillis" : {$subtract : [new Date(), "$DateOfBirth"] } } }, { $project : {"age" : {$divide : ["$ageInMillis", 31558464000] }}}, // take the floor of the previous number: { $project : {"age" : {$subtract : ["$age", {$mod : ["$age",1]}]}}}, { $group : { _id : "$age", Total : { $sum : 1} } }, { $sort : { "Total" : -1 } } ]) 
+8
source

There are not enough DateTime operators and math operators to predict the date. But you can create age ranges by composing a dynamic query:

Define date ranges as clipping dates as

dt18 = today - 18 dt25 = today - 25 ... dt65 = today - 65

Then follow the nested conventions in which you gradually use clipping dates as age group markers, for example:

 db.folks.save({ "_id" : 1, "bd" : ISODate("2000-02-03T00:00:00Z") }); db.folks.save({ "_id" : 2, "bd" : ISODate("2010-06-07T00:00:00Z") }); db.folks.save({ "_id" : 3, "bd" : ISODate("1990-10-20T00:00:00Z") }); db.folks.save({ "_id" : 4, "bd" : ISODate("1964-09-23T00:00:00Z") }); db.folks.aggregate( { $project: { ageGroup: { $cond: [{ $gt: ["$bd", ISODate("1995-03-19")] }, "age0_18", { $cond: [{ $gt: ["$bd", ISODate("1988-03-19")] }, "age18_25", "age25_plus"] }] } } }, { $group: { _id: "$ageGroup", count: { $sum: 1 } } }) 
+1
source

All Articles