计算用户的平均值与所有平均值相比

时间:2016-01-29 19:19:37

标签: mongodb aggregation-framework

我有一个包含如此数据的文档:

{  
   "user":"john",
   "games":[  
      {  
         "id":1,
         "score":100
      }
   ]
},
{  
   "user":"ben",
   "games":[  
      {  
         "id":1,
         "score":110
      }
   ]
},
{  
   "user":"john",
   "games":[  
      {  
         "id":2,
         "score":110
      }
   ]
},
{  
   "user":"steve",
   "games":[  
      {  
         "id":2,
         "score":120
      }
   ]
}

我希望能够计算出约翰斯"与其他人相比,他所有比赛的平均得分。

例如,

John在第一场和第二场比赛中都参赛,因此我们会计算每位用户在ID为1和id为2的比赛中的平均得分。

ID 1应提供(100 + 110 / 2) = 107.5,ID 2应提供(120 + 110 / 2) = 115

我希望得到John在他给出的所有比赛中的平均得分(他也可以有多个得分)之间的差异,并得到差异。

例如,他在ID 1中有一个条目,因此他的平均分为100。他的得分与所有玩家的总ID 1平均值之间的差异为-7.5,对于ID 2,他的平均得分为110,他的差异为-5,因此他的总差异为{ {1}}。

我试图这样做:

(-7.5 + -5 / 2) = -6.25

这给了我John在所有游戏中按唯一游戏ID分组的分数,但是,我不确定如何完成第二部分,我将其分数与所有其他用户进行比较。

2 个答案:

答案 0 :(得分:1)

获取所有人'平均每场比赛:

db.scores.aggregate(
  {
     $unwind : "$games"
  },
  {
    $group: {
       "_id" : "$games.id",
       "gameAvg" : {$avg : "$games.score"},
    }
  }
)

输出如:

{ 
    "_id" : NumberInt(2), 
    "gameAvg" : 115.0
}
{ 
    "_id" : NumberInt(1), 
    "gameAvg" : 105.0
}

得到约翰'平均每场比赛:

db.scores.aggregate(
  {
     $unwind : "$games"
  },
  {
     $match : {
        "user" : "john", 
     }
  },
  {
    $group: {
       "_id" : "$games.id",
       "gameAvg" : {$avg : "$games.score"},
    }
  }
)

输出如:

{ 
    "_id" : NumberInt(2), 
    "gameAvg" : 110.0
}
{ 
    "_id" : NumberInt(1), 
    "gameAvg" : 100.0
}
  1. 所以你可以运行逻辑来计算每个游戏2个循环的差异
  2. 获取所有差异的AVG,即您想要的答案

答案 1 :(得分:0)

要在同一个聚合管道中执行这两项操作,您可以执行$ push的用户文档,然后使用$ unwind来获取用户平均值。

db.games.aggregate([ 
    { 
        $unwind: '$games' 
    }, 
    { 
        $group: { 
            _id: '$games.id', 
            score: {$avg: '$games.score'}, 
            user_scores: { 
                $push : { user: '$user', score: '$games.score' } 
            } 
        } 
     }, 
     { 
         $unwind: '$user_scores' 
     }, 
     {
         $group: { 
             _id: { user: '$user_scores.user', game: '$_id' },
             user_avg: { $avg: '$user_scores.score' }, 
             group_avg: { $first: '$score' }
         }
     }, 
     {
         $project: { 
             _id: 0, 
             user: '$_id.user', 
             game: '$_id.game', 
             avg_diff: { $subtract: ['$group_avg', '$user_avg'] } 
         }
     }
]);