2016-09-14 7 views
3

私は、フォームMongoの集約 - フィールドの値の異なるグループのために蓄積

{name: String, score: Int} 

Player書類を持っていると私はグループが選手

{groupName: String, players: [ObjectID]} 

選手のリストを表すGroup文書を持っている場合複数のグループに属することができます。

Groupでグループ化されたPlayer文書の集合を作成したいとします(例えば、各グループのプレイヤーの得点の合計を1つの集約パイプラインで取得します)。 GroupIDによって、その後$groupそれらが関連付けられているGroup文書へのポインタをPlayerドキュメントをお返し

=>:

オプションは、私は承知しているの。しかし、私はPlayerコレクションを変更する必要はありません。 (パイプライン中でGroupIDを文書に追加する方法がありますか?)

=>グループごとに別々の呼び出しを行い、照会されている現在のグループのプレーヤーだけをフィルタリングするために$matchステージを使用しますために。しかし、私は単一の、簡単な呼び出しを行うことを好む。

どのようにしてこのような集約を達成できますか? MongoDB集約にはこれに対応するものがありますか?

(ところで、コールが行われている場所で、グループとプレイヤーをマップしておけば問題ありませんので、プレイヤーのリストを引数として渡すオプションは実際には公正なゲームです)

答えて

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

あなたはあなたのためにいくつかのMongoの方法を包み込む集約フレームワークパッケージを取得することにより、集約のためのサポートを追加することができます。ちょうど流星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" 
    }} 
]) 
関連する問題