我有一个存储在mongo中的用户群。用户可以记录他们的出生日期。 我需要生成一个汇总用户按年龄的报告。
我现在有一条管道,按照出生年份对用户进行分组。然而,这不够精确,因为大多数人不是1月1日出生的;因此,即使他们出生于1970年,他们也可能还不到43岁。
db.Users.aggregate([
{ $match : { "DateOfBirth" : { $exists : true} } },
{ $project : {"YearOfBirth" : {$year : "$DateOfBirth"} } },
{ $group : { _id : "$YearOfBirth", Total : { $sum : 1} } },
{ $sort : { "Total" : -1 } }
])
您是否知道在聚合框架内是否可以执行某种算法来精确计算用户的年龄?或者这只能用MapReduce来实现吗?
答案 0 :(得分:8)
似乎整个事情都可能发布刚刚发布的新Mongo 2.4版本,支持额外的Date操作(即“$ subtract”)。
我是这样做的:
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 } }
])
答案 1 :(得分:1)
没有足够的dateTime运算符和数学运算符来预测日期。但您可以通过编写动态查询来创建年龄范围:
将日期范围定义为截止日期
dt18 =今天 - 18 dt25 =今天 - 25 ... dt65 =今天 - 65
然后执行嵌套条件,逐步使用截止日期作为年龄组标记,如下所示:
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
}
}
})