2016-09-14 29 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" 
    }} 
])