2013-03-19 18 views
6

私はmongoにユーザーベースを格納しています。ユーザーに生年月日が記録されます。 ユーザーを集計するレポートを年齢:まで実行する必要があります。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

私があれば、 '、$のsubtract'演算子は、あなたのタスクに適しているが、残念ながらそれは現在の安定版:) – user20140268

+0

まあで' Dates'をサポートしていないと思います日付はミリ秒単位で格納されますが、解決方法はミリ秒単位で(long型として)差し引かれ、日付形式に変換されます。 – user

答えて

8

をに思えます新しいMongo 2.4バージョンがリリースされたばかりで、追加の日付操作(つまり、 "$ 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 } } 
]) 
+0

は、「新着(%)」の「%」ではありませんか? Btw、素晴らしい答え。 – joao

+0

しかし、私が知る限り、うるう年は処理しません。このようなものを統合するのはいかがですか? –

+0

関数isLeap(year){ return year%4 == 0 &&(year%100!= 0 || year%400 == 0); } –

1

日付を投影するのに十分なdateTime演算子と数式演算子がありません。 18 DT25 =今日 - - 25 ... dt65 dt18 =今日

としてカットオフ日付としてあなたの日付範囲を定義

:しかし、あなたは動的なクエリを構成することにより、年齢範囲を作成することができるかもしれません=今日 - 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 
     } 
    } 
})