所以我想做的是编写一个查询,该查询将返回每个年龄段的人数 - 而不是增量。所以已经活了 1、2、3、...67...99...年的人数。
我不熟悉 NoSQL,但我知道由于时间在不断变化,年龄计数必须定期更新/刷新。我在想的是拥有一个集合或一些具有年龄键和值作为年龄的人数的东西。当创建一个新人时,它会增加与他或她同龄的人的数量 - 然后正如我之前所说,有一些东西可以更新它。
我想弄清楚的是,是否有一种方法可以在没有计数器的情况下主动获取所有不同年龄段的人数(实时)。或者,如果我必须使用计数器,我怎样才能让数据库自动递增计数器,这样我就不需要与程序交互?
最佳答案
您可以使用 MongoDB 的聚合框架来实现这一点。为了使其实时更新,您需要做的是:
- 通过从当前日期中减去出生日期 (
dob
) 投影一个ageMillis
字段。您将获得以毫秒为单位的年龄值。 - 将
ageMillis
除以一年中的毫秒数(在 JavaScript 中为 31536000000)并将其投影到ageDecimal
字段中。您不想使用此年龄进行分组,因为它包含小数。 - 投影
ageDecimal
字段和包含年龄小数部分的decimal
字段。您可以使用$mod
运算符执行此操作。 - 从
ageDecimal
中减去decimal
并将其投影到age
字段。这将为您提供以年为单位的年龄值。 - 按
age
字段分组并使用$sum
跟踪计数。基本上,您为该年龄段看到的每份文件加 1。 - 如果需要,按
age
字段排序。
mongo
shell 中的命令类似于下面的命令,使用 JavaScript 的 Date()
对象获取当前日期。如果您想在 Ruby 中执行此操作,则必须更改那部分代码并确保其余部分遵循 Ruby 驱动程序的语法。
db.collection.aggregate([
{ "$project" :
{
"ageMillis" : { "$subtract" : [ new Date(), "$dob" ]}
}
},
{ "$project" :
{
"ageDecimal" : { "$divide" : [ "$ageMillis", 31536000000 ]}
}
},
{ "$project" :
{
"ageDecimal" : "$ageDecimal",
"decimal" : { "$mod" : [ "$ageDecimal", 1 ]}
}
},
{ "$project" :
{
"age" : { "$subtract" : [ "$ageDecimal", "$decimal" ]}
}
},
{ "$group" :
{
"_id" : { "age" : "$age" },
"count" : { "$sum" : 1 }
}
},
{ "$sort" :
{
"_id.age" : 1
}
}
]);
这应该会给您想要的结果。请注意,aggregate()
方法返回一个游标。您必须遍历它才能获得结果。
关于ruby - 选择没有间隔的年龄计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24889408/