2017-02-24 64 views
1

我正在使用以下mongo db查询。它仅向我展示了我的人物角色数据的年龄组。按mongo db中的年龄组分组

db.amplifyindex.aggregate([ 
    { $unwind: "$demographic" }, 
    { $match : { 'demographic.is_latest':"active",   
    'demographic.date_of_birth' : { $exists : true} } }, 
    { $project : {"ageInMillis" : {$subtract : [new Date(), 
    "$demographic.date_of_birth"] } } }, 
    { $project : {"age" : {$divide : ["$ageInMillis", 31558464000] }}}, 
    { $project : {"age" : {$subtract : ["$age", {$mod : ["$age",1]}]}}}, 

    ]) 

此查询结果对象是:

{ 
"_id" : ObjectId("58a42cbbdb5d880c1e000029"), 
"age" : 29.0 
} 

我希望的方式来获得数据:

{ 
"_id" : ObjectId("58a42cbbdb5d880c1e000029"), 
"age" : 10-30 
"personas" : 10 
} 
在我的情况

完整的数据结构,给出如下:

{ 
"_id" : ObjectId("58a42cbbdb5d880c1e000029"), 
"persona_email" : "[email protected]", 
"company_id" : "1", 
"date_added" : ISODate("2017-02-15T10:23:15.000Z"), 
"demographic" : [ 
    { 
     "persona_fname" : "Hayden", 
     "middle_name" : "Jacobs", 
     "persona_lname" : "Schmeler", 
     "gender" : "male", 
     "date_of_birth" : ISODate("1987-06-16T19:00:00.000Z"), 
     "marital_status" : "single", 
     "height" : "2.1 feet", 
     "weight" : "5 kg", 
     "measurement" : { 
      "waist" : "34 inch" 
     }, 
     "disabilities" : "No", 
     "race" : "Asian", 
     "nationality" : "Jordan", 
     "life_cycle" : "empty nest", 
     "children" : { 
      "gender" : "female", 
      "date_of_birth" : ISODate("1987-06-16T19:00:00.000Z") 
     }, 
     "medicare_no" : "4916725587565", 
     "driving_licence_no" : "PACBALM420M", 
     "id_no" : "4485872783336", 
     "passport_no" : "OCRFHCNR", 
     "residential_address" : { 
      "unit_no" : 603, 
      "street_no" : "34863 Ondricka Viaduct Apt. 154", 
      "street_name" : "84799 Little Wall", 
      "suburb" : "West Virginia", 
      "postal_code" : "23873", 
      "state" : "Dominica", 
      "country" : "Cook Islands" 
     }, 
     "work_address" : { 
      "unit_no" : "6011865161287875", 
      "street_no" : "630 Beer Underpass Suite 372", 
      "street_name" : "87672 Lind Burg", 
      "suburb" : "West Virginia", 
      "postal_code" : "84356-3662", 
      "state" : "Qatar", 
      "country" : "British Indian Ocean Territory (Chagos Archipelago)" 
     }, 
     "shipping_address" : { 
      "unit_no" : "6011865161287875", 
      "street_no" : "8292 Langosh Drive Suite 065", 
      "street_name" : "9844 Nicolas Mount", 
      "suburb" : "West Virginia", 
      "postal_code" : "07014", 
      "state" : "Togo", 
      "country" : "Tunisia" 
     }, 
     "job_title" : "Geoscientists", 
     "employer_name" : "Aufderhar Group", 
     "income" : 72577, 
     "phone_numbers" : { 
      "work_phone" : "993-783-7499", 
      "home_phone" : "701.546.7016", 
      "mobile" : "1-346-729-4392" 
     }, 
     "emails" : { 
      "work_emails" : "[email protected]", 
      "personal_emails" : "[email protected]" 
     }, 
     "languages" : "italian", 
     "data_source" : "soldi", 
     "date_added" : ISODate("2017-02-15T10:23:15.000Z"), 
     "source" : "soldi", 
     "is_latest" : "inactive" 
    }, 
    { 
     "persona_fname" : "Julien", 
     "middle_name" : "Hirthe", 
     "persona_lname" : "Schaefer", 
     "gender" : "female", 
     "date_of_birth" : ISODate("1987-06-16T19:00:00.000Z"), 
     "marital_status" : "single", 
     "height" : "2.1 feet", 
     "weight" : "5 kg", 
     "measurement" : { 
      "waist" : "34 inch" 
     }, 
     "disabilities" : "No", 
     "race" : "Asian", 
     "nationality" : "Sudan", 
     "life_cycle" : "single", 
     "children" : { 
      "gender" : "female", 
      "date_of_birth" : ISODate("1987-06-16T19:00:00.000Z") 
     }, 
     "medicare_no" : "4024007131689860", 
     "driving_licence_no" : "OGOSUOIFSDN", 
     "id_no" : "5523297913341227", 
     "passport_no" : "WWZYTE489ZR", 
     "residential_address" : { 
      "unit_no" : 603, 
      "street_no" : "338 Mueller Gardens Suite 397", 
      "street_name" : "6302 Catalina Isle", 
      "suburb" : "West Virginia", 
      "postal_code" : "97534", 
      "state" : "Antarctica (the territory South of 60 deg S)", 
      "country" : "Turks and Caicos Islands" 
     }, 
     "work_address" : { 
      "unit_no" : "6011865161287875", 
      "street_no" : "8561 Jesus Ridges Apt. 662", 
      "street_name" : "1869 Josiah Wall Apt. 347", 
      "suburb" : "West Virginia", 
      "postal_code" : "14810", 
      "state" : "Zambia", 
      "country" : "Mongolia" 
     }, 
     "shipping_address" : { 
      "unit_no" : "6011865161287875", 
      "street_no" : "514 Heller Center", 
      "street_name" : "835 Paxton Cliffs Suite 040", 
      "suburb" : "West Virginia", 
      "postal_code" : "48942-3845", 
      "state" : "Palau", 
      "country" : "Belize" 
     }, 
     "job_title" : "Geoscientists", 
     "employer_name" : "Aufderhar Group", 
     "income" : 72577, 
     "phone_numbers" : { 
      "work_phone" : "(553) 892-7614 x573", 
      "home_phone" : "796.308.3001 x88799", 
      "mobile" : "+1-876-339-1755" 
     }, 
     "emails" : { 
      "work_emails" : "[email protected]", 
      "personal_emails" : "[email protected]" 
     }, 
     "languages" : "german", 
     "data_source" : "soldi", 
     "date_added" : ISODate("2017-02-15T10:23:15.000Z"), 
     "source" : "soldi", 
     "is_latest" : "active" 
    } 
] 
    } 

回答

1

在您的组管道中,c将年龄范围作为_id密钥的一部分并且这可以通过使用$concat"$cond"运营商来完成。考虑运行下面的管道,以获得期望的结果:

db.amplifyindex.aggregate([ 
    { "$unwind": "$demographic" }, 
    { "$match": { "demographic.is_latest": "active" } }, 
    { 
     "$project": { 
      "age": { 
       "$divide": [ 
        { 
         "$subtract": [ 
          new Date(), 
          { "$ifNull": ["$demographic.date_of_birth", new Date()] } 
         ] 
        }, 
        1000 * 86400 * 365 
       ] 
      } 
     } 
    }, 
    { 
     "$group": { 
      "_id": { 
       "$concat": [ 
        { "$cond": [ { "$lte": [ "$age", 0 ] }, "Unknown", ""] }, 
        { "$cond": [ { "$and": [ { "$gt": ["$age", 0 ] }, { "$lt": ["$age", 10] } ]}, "Under 10", ""] }, 
        { "$cond": [ { "$and": [ { "$gte": ["$age", 10] }, { "$lt": ["$age", 31] } ]}, "10 - 30", ""] }, 
        { "$cond": [ { "$and": [ { "$gte": ["$age", 31] }, { "$lt": ["$age", 51] } ]}, "31 - 50", ""] }, 
        { "$cond": [ { "$and": [ { "$gte": ["$age", 51] }, { "$lt": ["$age", 71] } ]}, "51 - 70", ""] }, 
        { "$cond": [ { "$gte": [ "$age", 71 ] }, "Over 70", ""] } 
       ] 
      }, 
      "personas": { "$sum": 1 } 
     } 
    }, 
    { "$project": { "_id": 0, "age": "$_id", "personas": 1 } } 
]) 

在上面的管道,我已经采取了对空日期字段的查询,并与$project$ifNull运营商取代了它管道。这将返回生日字段为空的当前日期,从而生成0岁的年龄,这将落入特殊的年龄段范围,因此需要包括所有文档,包括出生日期字段缺失的日期。

在该$concat运营商用于所有$cond表现的情况下,该组合是至关重要的,因为它作为一个case语句另有会有嵌套$cond运营商。

为了理解这个设计,从第三$cond表达

{ 
    "$cond": [ 
     { 
      "$and": [ 
       { "$gte": ["$age", 10] }, 
       { "$lt": ["$age", 31] } 
      ] 
     }, 
     "10 - 30", // matching if 
     "" // else 
    ] 
}, 

其基本上表示所述逻辑

if ("$age" >= 10 && "$age" < 31) { return "10 - 30"; } 
else return ""; 

$concat$cond运营商为使用时是非常有用的表达式将返回一个空的VA除了匹配的一个,这反过来会返回年龄组。

例如,30.645411时代将返回

"$concat": [ "", "", "10 - 30", "", "", "" ] 

,然后让你用"10 - 30".

+1

价值_id非常感谢你。完美的帮助。 @chridam –

+0

你也可以通过使用[bucket](https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/)及其边界来改善你的查询 –