Die Antwort wäre viel einfacher, wenn Sie Alter in dem Originaldokument zu speichern wurden (wie Dmitry geschrieben, könnte man einfach eine gerade avgAge:{$avg:"$age"}
in Ihrem $group
Schritt tun.
Aggregation-Framework ziemlich raffinierte und hat viele coole Operatoren, die Sie zu berechnen, diese fehlenden Altersfeld „on the fly“
ich werde speichern jeden Schritt der Aggregation in einer variablen ermöglichen, so dass es leichter zu sehen ist, was vor sich geht.
today = new Date();
// split today and bday into numerical year and numerical day-of-the-year
project1= {
"$project" : {
"sex" : 1,
"todayYear" : {
"$year" : today
},
"todayDay" : {
"$dayOfYear" : today
},
"by" : {
"$year" : "$bday"
},
"bd" : {
"$dayOfYear" : "$bday"
}
}
};
// calculate age in days by subtracting bday in days from today in days
project2 = {
"$project" : {
"sex" : 1,
"age" : {
"$subtract" : [
{
"$add" : [
{
"$multiply" : [
"$todayYear",
365
]
},
"$todayDay"
]
},
{
"$add" : [
{
"$multiply" : [
"$by",
365
]
},
"$bd"
]
}
]
}
}
};
// sum up for each sex the count and compute avg age (in days)
group = {
"$group" : {
"_id" : "$sex",
"total" : {
"$sum" : 1
},
"avgAge" : {
"$avg" : "$age"
}
}
};
// divide days by 365 to get age in years.
project3 = {
"$project" : {
"_id" : 0,
"sex" : "$_id",
"total" : 1,
"averageAge" : {
"$divide" : [
"$avgAge",
365
]
}
}
};
Jetzt können Sie die Aggregation ausführen:
> db.client.find({},{_id:0})
{ "sex" : "male", "bday" : ISODate("2000-02-02T08:00:00Z") }
{ "sex" : "male", "bday" : ISODate("1987-02-02T08:00:00Z") }
{ "sex" : "female", "bday" : ISODate("1989-02-02T08:00:00Z") }
{ "sex" : "female", "bday" : ISODate("1993-11-02T08:00:00Z") }
> db.client.aggregate([ project1, project2, group, project3 ])
{
"result" : [
{
"sex" : "female",
"total" : 2,
"averageAge" : 21.34109589041096
},
{
"sex" : "male",
"total" : 2,
"averageAge" : 19.215068493150685
}
],
"ok" : 1
}
>
Der Grund, warum dies nicht einfach ist, ist derzeit Aggregation Framework nicht direkte Subtraktion der Daten unterstützt. Bitte stimmen Sie für https://jira.mongodb.org/browse/SERVER-6239, die für die nächste Hauptversion ausgerichtet ist - sobald es implementiert ist, sollte es Subtraktion von Daten direkt zulassen (obwohl Sie es immer noch in die passende Granularität konvertieren müssen, Jahre in diesem Fall wahrscheinlich).
Beachten Sie, dass Sie die Felder sexCount oder avgAge im ersten Schritt nicht projizieren müssen, da dies die Felder sind, die Sie im Schritt $ group berechnen. –