2016-09-14 28 views
3

如果我有形式蒙戈聚集 - 積累了場的值的不同羣體

{name: String, score: Int} 

Player文件和我有Group文件,其中基團代表的球員

{groupName: String, players: [ObjectID]} 

玩家名單可以屬於多個組。

我想要做一個Player文件的聚合,按Group分組(如得到每個組的玩家總分數和一個聚合管道)。

選擇我所知道的:

=>由GroupIDPlayer文檔回到指針Group文檔他們一個關聯,然後$group。但我更喜歡不必修改Player集合。 (也許有一種方法可以在流水線中將「GroupIDs」添加到文檔中?)

=>爲每個組分別調用一次,並使用$match階段過濾到當前所查詢組中的玩家對於。但我更喜歡做一個簡單的電話。

我該如何實現這樣的聚合? MongoDB Aggregation是否有適用於此的東西?

(順便說一下,在進行調用的內存中將組和玩家映射到對方並不是一個問題,因此涉及將玩家列表作爲參數的選項確實是公平的遊戲。)

回答

1

您可以使用$lookup運算符爲此。考慮運行以下聚集管道:

蒙戈外殼:

db.group.aggregate([ 
    { "$unwind": "$players" }, 
    { 
     "$lookup": { 
      "from": "players", 
      "localField": "players", 
      "foreignField": "_id", 
      "as": "players_join" 
     } 
    }, 
    { "$unwind": "$players_join" }, 
    { 
     "$group": { 
      "_id": { 
       "groupName": "$groupName", 
       "name": "$players_join.name" 
      }, 
      "totalScore": { "$sum": "$players_join.score" } 
     } 
    } 
]) 

您可以通過獲取聚合框架包,其中包了一些蒙戈方法添加的聚合支持。只是流星添加meteorhacks:aggregate你應該做生意。這會在Meteor中爲你的集合添加一個聚合方法。

1

Additionnaly到@Chridam答案,以避免混淆集合/場/放鬆的別名,我的建議是:

db.Group.aggregate([ 
    {$unwind:"$players"}, 
    {$lookup: { 
    from:"Player", 
    localField:"players", 
    foreignField:"_id", 
    as:"P" } 
    }, 
    {$unwind:"$P"}, 
    {"$group":{ 
    total: {$sum:"$P.score"}, 
    _id:"$_id" 
    }} 
])