2017-04-24 116 views
2

我有一個像學生的文件收集匹配組總:聚合框架需要的字段值

{ 
     "_id" : 1, 
     "Student" : "Sim", 
     "Test1" : 59, 
     "Test2" : 94, 
     "Test3" : 81 
} 
{ 
     "_id" : 2, 
     "Student" : "Sam", 
     "Test1" : 60, 
     "Test2" : 77, 
     "Test3" : 81 
} 

我需要精細學生測試1名得分少腋臭的所有測試的總平均整個類,使用聚合框架。

我可以得到以下組部分的總平均水平,但,,,

如果

db.students.aggregate([ 
    {$project: { 
     Stu: '$Student', 
     Test1: '$Test1', 
     av: {$avg: ['$Test1', '$Test2', '$Test3']} 
    } }, 
    {$group: { _id: null, 
       totAvg: {$avg : '$av'} 
    } 
]); 

那時我失去了學生和test1的一場比賽中部分比較。

回答

1

使用$push + $filter

$push$group階段把所有的test1馬克和Student名之後$filter$project階段比較他們對總平均標記和保持匹配的記錄。

您可以將$filter包裝在$map中以僅投影學生姓名。

db.students.aggregate([{ 
     $project: { 
      Stu: '$Student', 
      Test1: '$Test1', 
      av: { 
       $avg: ['$Test1', '$Test2', '$Test3'] 
      } 
     } 
    }, 
    { 
     $group: { 
      _id: null, 
      studentTest1: { 
       $push: { 
        "Student": "$Stu", 
        "Test1": "$Test1" 
       } 
      }, 
      totAvg: { 
       $avg: '$av' 
      } 
     } 
    }, 
    { $project: 
    { lessthanAvgStudentNames: 
     { 
      $map: 
      { 
       input: { 
        $filter: { 
         input: "$studentTest1", 
         as: "resultf", 
         cond: { 
          $lt: ["$$resultf.Test1", "$totAvg"] 
         } 
        } 
       }, 
       as: "resultm", 
       in: "$$resultm.Student" 
      } 
     } 
    } 
    } 
]); 
+0

謝謝!!這樣可行! ($ filter,對我來說是新的。,,,)。我將如何只項目名稱? – Rachel

+0

不客氣。更新答案以包含'$ map'以僅投影學生姓名。這裏的鏈接https://docs.mongodb.com/manual/reference/operator/aggregation/map/和https://docs.mongodb.com/manual/reference/operator/aggregation/filter/ – Veeram

+0

你是一位天才!太感謝了! – Rachel