如何获得数组中值的平均值?

时间:2016-04-16 19:36:30

标签: mongodb mongodb-query aggregation-framework

在这段代码中,我有一份医生文档,在文档中有 一系列医生的病人。在这种情况下,我想找出我阵中所有病人的平均年龄。我怎么能这样做?

  {
            "_id" : ObjectId("57113238bde91693e9ff69e7"),
            "docname" : "Arthur Hovsepyan",
            "job_desc" : "Hepatologist",
            "sex" : "male",
            "jobtype" : "fulltime",
            "office" : "room 448",
            "email" : "arturchik@hotmail.com",
            "phone_number" : 862124343,
            "address" : "68 Peterburg street,waterford",
            "hours" : 12,
            "patients" : [
                    {
                            "name" : "Jenny Power",
                            "ward_no" : 1,
                            "sex" : "female",
                            "termdays" : 2,
                            "illness_type" : "minor",
                            "age" : 22,
                            "phone_number" : 877285221,
                            "address" : "63 Johnston street ,Waterford"
                    },
                    {
                            "name" : "Marie Peters",
                            "ward_no" : 2,
                            "sex" : "female",
                            "termdays" : 0,
                            "illness_type" : "minor",
                            "age" : 21,
                            "phone_number" : 862145992,
                            "address" : "99 Grange,Waterford"
                    },
                    {
                            "name" : "Philip John",
                            "ward_no" : 2,
                            "sex" : "male",
                            "termdays" : 10,
                            "illness_type" : "serious",
                            "age" : 31,
                            "phone_number" : 861125981,
                            "address" : "12 Monvoy Bridge,Waterford"
                    },
                    {
                            "name" : "Marta Peters",
                            "ward_no" : 3,
                            "sex" : "female",
                            "termd7ays" : 0,
                            "illness_type" : "minor",
                            "age" : 31,
                            "phone_number" : 862125981,
                            "address" : "100 Grange Manor,Waterford"
                    }
            ]
    }

3 个答案:

答案 0 :(得分:0)

对于此问题,您必须首先解开内部患者阵列,然后在 patients.age 属性上应用 $ avg 运算符。您的查询将是: -

db. collection.aggregate([
    {
    "$unwind": "$patients"
    },  
    {
        $group : {
                _id:{
                        "docname" : "$docname"
                    },
                avg_age : {$avg : "$patients.age"}
             }

        }
])

答案 1 :(得分:0)

如果你有MongoDB 3.2+,你可以在$avg阶段使用$project,这样可以减轻服务器资源的压力。但是,如果您的MongoDB版本低于3.2,请考虑ashisahu发布的解决方案。

db.collection.aggregate([
  {
    $project:{
      docname: 1,
      job_desc: 1,
      sex: 1,
      jobtype: 1,
      office: 1,
      email: 1,
      phone_number: 1,
      address: 1,
      hours: 1,
      patients: 1,
      avg_age_of_patients:{$avg:"$patients.age"}
     }
   }
])

这将输出以下文件。 (见avg_age_of_patients字段)

{ 
    "_id" : ObjectId("57113238bde91693e9ff69e7"), 
    "docname" : "Arthur Hovsepyan", 
    "job_desc" : "Hepatologist", 
    "sex" : "male", 
    "jobtype" : "fulltime", 
    "office" : "room 448", 
    "email" : "arturchik@hotmail.com", 
    "phone_number" : 8.62124343E8, 
    "address" : "68 Peterburg street,waterford", 
    "hours" : 12.0, 
    "patients" : [
        {
            "name" : "Jenny Power", 
            "ward_no" : 1.0, 
            "sex" : "female", 
            "termdays" : 2.0, 
            "illness_type" : "minor", 
            "age" : 22.0, 
            "phone_number" : 8.77285221E8, 
            "address" : "63 Johnston street ,Waterford"
        }, 
        {
            "name" : "Marie Peters", 
            "ward_no" : 2.0, 
            "sex" : "female", 
            "termdays" : 0.0, 
            "illness_type" : "minor", 
            "age" : 21.0, 
            "phone_number" : 8.62145992E8, 
            "address" : "99 Grange,Waterford"
        }, 
        {
            "name" : "Philip John", 
            "ward_no" : 2.0, 
            "sex" : "male", 
            "termdays" : 10.0, 
            "illness_type" : "serious", 
            "age" : 31.0, 
            "phone_number" : 8.61125981E8, 
            "address" : "12 Monvoy Bridge,Waterford"
        }, 
        {
            "name" : "Marta Peters", 
            "ward_no" : 3.0, 
            "sex" : "female", 
            "termd7ays" : 0.0, 
            "illness_type" : "minor", 
            "age" : 31.0, 
            "phone_number" : 8.62125981E8, 
            "address" : "100 Grange Manor,Waterford"
        }
    ], 
    "avg_age_of_patients" : 26.25
}

答案 2 :(得分:0)

您可以使用.aggregate()方法执行此操作,该方法提供对聚合管道的访问。据说最好的方法是在$avg阶段使用$project累加器运算符,如果你使用的是MongoDB 3.2或更新版本。

db.collection.aggregate([ 
    { "$project": { 
        "averageAge": { "$avg": "$patients.age" } 
    }}
]) 

从MongoDB 3.0开始,你需要一种不同的方法。你可以先$project你的文件并返回一个" age"您的患者"患者"使用$map运算符。从那里开始,您需要使用$unwind运算符对该数组进行反规范化,然后_id使用$group文档对其进行反规范化,并使用$avg运算符返回&#34的平均值;年龄&#34 ;.

db.collection.aggregate([ 
    { "$project": { 
        "agePatients": { 
            "$map": { 
                "input": "$patients", 
                "as": "p",
                "in": "$$p.age" 
            } 
        } 
    }}, 
    { "$unwind": "$agePatients" }, 
    { "$group": { 
        "_id":  "$_id", 
        "averageAge": { "$avg": "$agePatients" } 
    }} 
])

返回:

{ 
    "_id" : ObjectId("57113238bde91693e9ff69e7"), 
    "averageAge" : 26.25 
}