MongoDB对同一文档中的多个字段进行分组和计算结果

时间:2018-08-28 14:13:56

标签: mongodb mongodb-query aggregation-framework

关于MongoDB聚合框架,我可以帮您吗?我试图从以下游戏集合中建立英超联赛表:

{ 
    "_id" : ObjectId("5b39fec4b5f8df161d259f36"), 
    "gameWeek" : 1, 
    "homeTeam" : "Arsenal", 
    "awayTeam" : "Leicester", 
    "homeGoals" : 2, 
    "awayGoals" : 1 
}, { 
    "_id" : ObjectId("5b39ffc2b5f8df161d259f6d"), 
    "gameWeek" : 2, 
    "homeTeam" : "Arsenal", 
    "awayTeam" : "Sunderland", 
    "homeGoals" : 1, 
    "awayGoals" : 1 
}, { 
    "_id" : ObjectId("5b39ffe8b5f8df161d259f7f"), 
    "gameWeek" : 2, 
    "homeTeam" : "Sunderland", 
    "awayTeam" : "Manchester United", 
    "homeGoals" : 1, 
    "awayGoals" : 1 
}, { 
    "_id" : ObjectId("5b492cbea5aef964f0911cce"), 
    "gameWeek" : 1, 
    "homeTeam" : "Manchester United", 
    "awayTeam" : "Leicester", 
    "homeGoals" : 0, 
    "awayGoals" : 1 
}

我希望得到以下结果:

{ 
    "_id" : "Arsenal", 
    "team" : "Arsenal", 
    "gamesPlayed" : 2, 
    "goalsFor" : 3, 
    "goalsAgainst" : 2, 
    "goalsDifference" : 1, 
    "gamesWon" : 1, 
    "gamesDraw" : 1, 
    "gamesLost" : 0, 
    "points" : 4 
}, { 
    "_id" : "Leicester", 
    "team" : "Leicester", 
    "gamesPlayed" : 2, 
    "goalsFor" : 2, 
    "goalsAgainst" : 2, 
    "goalsDifference" : 0, 
    "gamesWon" : 1, 
    "gamesDraw" : 0, 
    "gamesLost" : 1, 
    "points" : 3 
}, { 
    "_id" : "Sunderland", 
    "team" : "Sunderland", 
    "gamesPlayed" : 2, 
    "goalsFor" : 2, 
    "goalsAgainst" : 2, 
    "goalsDifference" : 0, 
    "gamesWon" : 0, 
    "gamesDraw" : 2, 
    "gamesLost" : 0, 
    "points" : 2 
}, { 
    "_id" : "Manchester United", 
    "team" : "Manchester United", 
    "gamesPlayed" : 2, 
    "goalsFor" : 1, 
    "goalsAgainst" : 2, 
    "goalsDifference" : -1, 
    "gamesWon" : 0, 
    "gamesDraw" : 1, 
    "gamesLost" : 1, 
    "points" : 1 
}

其中:

  • gamesPlayed-玩过的游戏总数,
  • goalsFor-团队制定的总目标,
  • goalsAgainst-进球总数,
  • goalsDifference-'goalsFor'减去'goalsAgainst'
  • 点-计算得出的每场获胜游戏3分和每场平局1分。

到目前为止,我有以下查询以建立一支由homeTeam团队支持的团队:

db.football_matches.aggregate([
    { 
        $group: { 
            _id:  "$homeTeam",  
            gamesPlayed : { $sum: NumberInt(1) }, 
            goalsFor: { $sum:  "$homeGoals"  }, 
            goalsAgainst: { $sum:  "$awayGoals" }, 
            gamesWon: { $sum: { $cond: { if: { $gt: [ "$homeGoals",  "$awayGoals" ]}, then: NumberInt(1), else: NumberInt(0) } }}, 
            gamesDraw: { $sum: { $cond: { if: { $eq: [ "$homeGoals",  "$awayGoals" ]}, then: NumberInt(1), else: NumberInt(0) } }},
            gamesLost: { $sum: { $cond: { if: { $lt: [ "$homeGoals",  "$awayGoals" ]}, then: NumberInt(1), else: NumberInt(0) } }}
        }
     }, { 
         $project: { 
             team:  "$_id" , 
             gamesPlayed:  "$gamesPlayed", 
             goalsFor:  "$goalsFor", 
             goalsAgainst:  "$goalsAgainst", 
             goalsDifference: { $subtract: [ "$goalsFor", "$goalsAgainst"] }, 
             gamesWon: "$gamesWon", 
             gamesDraw: "$gamesDraw",
             gamesLost: "$gamesLost",
             points: { $add: [ {$multiply: [ "$gamesWon", NumberInt(3)]}, {$multiply: [ "$gamesDraw", NumberInt(1)]} ]}
        }
     }, {
       $sort: { points: -1, goalsDifference: -1 }
    }
])

理论上,我需要将以下分组结果与另一个类似的group语句结合起来,在该语句中,将对awayTeam字段执行类似的操作:

{
    $group: { 
        _id:  "$awayTeam",  
        gamesPlayed : { $sum: NumberInt(1) }, 
        goalsFor: { $sum:  "$awayGoals"  }, 
        goalsAgainst: { $sum:  "$homeGoals" }, 
        gamesWon: { $sum: { $cond: { if: { $gt: [ "$awayGoals",  "$homeGoals" ]}, then: NumberInt(1), else: NumberInt(0) } }}, 
        gamesDraw: { $sum: { $cond: { if: { $eq: [ "$awayGoals",  "$homeGoals" ]}, then: NumberInt(1), else: NumberInt(0) } }},
        gamesLost: { $sum: { $cond: { if: { $lt: [ "$awayGoals",  "$homeGoals" ]}, then: NumberInt(1), else: NumberInt(0) } }}
    }
 } 

我该怎么做?非常感谢你。如果之前曾问过类似的问题,请接受我的道歉。

1 个答案:

答案 0 :(得分:1)

您可以尝试使用$facet$replaceRoot$unwind$concatArrays进行下面的汇总,最后再进行一个$group阶段

db.collection.aggregate([
  { "$facet": {
    "first": [
      { "$group": {
        "_id": "$homeTeam",
        "gamesPlayed": { "$sum": 1 },
        "goalsFor": { "$sum": "$homeGoals" },
        "goalsAgainst": { "$sum": "$awayGoals" },
        "gamesWon": {
          "$sum": { "$cond": { "if": { "$gt": [ "$homeGoals", "$awayGoals" ] }, "then": 1, "else": 0 } }
        },
        "gamesDraw": {
          "$sum": { "$cond": { "if": { "$eq": [ "$homeGoals", "$awayGoals" ] }, "then": 1, "else": 0 } }
        },
        "gamesLost": {
          "$sum": { "$cond": { "if": { "$lt": [ "$homeGoals", "$awayGoals" ] }, "then": 1, "else": 0 } }
        }
      }},
      { "$project": {
        "team": "$_id",
        "gamesPlayed": "$gamesPlayed",
        "goalsFor": "$goalsFor",
        "goalsAgainst": "$goalsAgainst",
        "goalsDifference": { "$subtract": [ "$goalsFor", "$goalsAgainst" ] },
        "gamesWon": "$gamesWon",
        "gamesDraw": "$gamesDraw",
        "gamesLost": "$gamesLost",
        "points": { "$add": [{ "$multiply": [ "$gamesWon", 3 ] }, { "$multiply": [ "$gamesDraw", 1 ] }] }
      }},
      { "$sort": { "points": -1, "goalsDifference": -1 } }
    ],
    "second": [
      { "$group": {
        "_id": "$awayTeam",
        "gamesPlayed": { "$sum": 1 },
        "goalsFor": { "$sum": "$awayGoals" },
        "goalsAgainst": { "$sum": "$homeGoals" },
        "gamesWon": {
          "$sum": { "$cond": { "if": { "$gt": [ "$awayGoals", "$homeGoals" ] }, "then": 1, "else": 0 } }
        },
        "gamesDraw": {
          "$sum": { "$cond": { "if": { "$eq": [ "$awayGoals", "$homeGoals" ] }, "then": 1, "else": 0 } }
        },
        "gamesLost": {
          "$sum": { "$cond": { "if": { "$lt": [ "$awayGoals", "$homeGoals" ] }, "then": 1, "else": 0 } }
        }
      }},
      { "$project": {
        "team": "$_id",
        "gamesPlayed": "$gamesPlayed",
        "goalsFor": "$goalsFor",
        "goalsAgainst": "$goalsAgainst",
        "goalsDifference": { "$subtract": [ "$goalsFor", "$goalsAgainst" ] },
        "gamesWon": "$gamesWon",
        "gamesDraw": "$gamesDraw",
        "gamesLost": "$gamesLost",
        "points": { "$add": [{ "$multiply": [ "$gamesWon",3 ] }, { "$multiply": [ "$gamesDraw",1 ] } ] }
      }},
      { "$sort": { "points": -1, "goalsDifference": -1 } }
    ]
  }},
  { "$project": {
    "data": {
      "$concatArrays": [ "$first", "$second" ]
    }
  }},
  { "$unwind": "$data" },
  { "$replaceRoot": { "newRoot": "$data" } },
  { "$group": {
    "_id": "$_id",
    "gamesPlayed": { "$sum": "$gamesPlayed" },
    "goalsFor": { "$sum": "$goalsFor" },
    "goalsAgainst": { "$sum": "$goalsAgainst" },
    "gamesWon": { "$sum": "$gamesWon" },
    "gamesDraw": { "$sum": "$gamesDraw" },
    "gamesLost": { "$sum": "$gamesLost" }
  }}
])