Javascript mongo聚合-为字段的不同值组进行累积

Javascript mongo聚合-为字段的不同值组进行累积,javascript,mongodb,meteor,aggregation-framework,Javascript,Mongodb,Meteor,Aggregation Framework,如果我有Player表单的文档 {name: String, score: Int} 我有Group文档,其中Group代表玩家列表 {groupName: String, players: [ObjectID]} 玩家可以属于多个组 我想对Player文档进行聚合,按Group分组(例如,通过一个聚合管道获取每个组的玩家分数总和) 我知道的选项有: =>给Playerdocs返回指针,指向与其关联的Group文档,然后通过GroupID给$Group。但是我不想修改Player集合。(也许

如果我有
Player
表单的文档

{name: String, score: Int}
我有
Group
文档,其中Group代表玩家列表

{groupName: String, players: [ObjectID]}
玩家可以属于多个组

我想对
Player
文档进行聚合,按
Group
分组(例如,通过一个聚合管道获取每个组的玩家分数总和)

我知道的选项有:

=>给
Player
docs返回指针,指向与其关联的
Group
文档,然后通过
GroupID
$Group
。但是我不想修改
Player
集合。(也许有一种方法可以在管道中向文档“添加”
GroupID
s?)

=>为每个组单独呼叫,并使用
$match
阶段筛选当前组中的玩家。但我更喜欢打一个简单的电话

如何实现这样的聚合?MongoDB聚合是否有适用于此的功能


(顺便说一句,将组和玩家相互映射到进行调用的内存中不是问题。因此,将玩家列表作为参数传递的选项确实是公平的。)

您可以使用操作符来实现这一点。考虑运行以下聚合管道:

Mongo shell:

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" }
        }
    }
])

您可以通过获取聚合框架包来添加对聚合的支持,该包为您封装了一些Mongo方法。只要meteor add,你就应该开始做生意了。这将向Meteor中的集合添加聚合方法

除了@Chridam answer之外,为了避免混淆集合/字段/展开别名,我建议:

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