2016-04-22 12 views
2

私は、コレクションのアカウントを持っています。取引には異なるフィールドを設定することができます:MongoDBの集約グループの_idは

{ 
    "_id": ObjectId("571a0e145d29024733793d06"), 
    "amount": 100, 
    "type": "earned", 
    "account": ObjectId("571a0e145d29024733793cfe"), 
    "user": ObjectId("571a0e145d29024733793cfc"), 

}, 
{ 
    "_id": ObjectId("571a0e145d29024733793d04"), 
    "amount": 300, 
    "type": "spent", 
    "account": ObjectId("571a0e145d29024733793cfe"), 
    "user": ObjectId("571a0e145d29024733793cfc") 
}, 
{ 
    "_id": ObjectId("571a0e145d29024733793d07"), 
    "amount": 100, 
    "type": "transfer", 
    "sourceAccount": ObjectId("571a0e145d29024733793cfd"), 
    "destinationAccount": ObjectId("571a0e145d29024733793cfe"), 
    "user": ObjectId("571a0e145d29024733793cfc"), 
} 

各アカウントで統計情報のグループを作成します。 私は、データベースに集約フレームワーククエリを書いた:

db.transactions.aggregate([ 

    { $match: { user: user._id } }, 

    { 
    $group: { 
     _id: '$account', 

     earned: { 
     $sum: { 
      $cond: [{ $eq: ['$type', 'earned'] }, '$amount', 0] 
     } 
     }, 

     spent: { 
     $sum: { 
      $cond: [{ $eq: ['$type', 'spent'] }, '$amount', 0] 
     } 
     }, 

     deposits: { 
     $sum: { 
      $cond: [{ $eq: ['$type', 'transfer'] }, '$amount', 0] 
     } 
     }, 

     withdrawal: { 
     $sum: { 
      $cond: [{ $eq: ['$type', 'transfer'] }, '$amount', 0] 
     } 
     }, 

     maxEarned: { 
     $max: { 
      $cond: [{ $eq: ['$type', 'earned'] }, '$amount', 0] 
     } 
     }, 

     maxSpent: { 
     $max: { 
      $cond: [{ $eq: ['$type', 'spent'] }, '$amount', 0] 
     } 
     }, 

     count: { $sum: 1 } 

    } 
    } 
]); 

しかし、それは正しく動作しません。フィールド勘定科目の取引の場合にのみ機能します。 フィールドアカウントまたはsourceAccountまたはdestinationAccountでグループ化したい。

私も "_id" フィールドに書き込みを試してみました:

_id: { account: '$account', sourceAccount: '$sourceAccount', destinationAccount: '$destinationAccount' } 

または

_id: {$or: ['$account', '$sourceAccount', '$destinationAccount']} 

または

_id: {$in: ['$account', '$sourceAccount', '$destinationAccount']} 

しかし、それは間違っているグループを作るか、または動作しません。

どのようにして異なるフィールドからグループ化できますか?

答えて

1

には、指定した条件指定されたキーでグループを評価する_id式として$cond演算子を使用します。 $condオペレータは、フィールドが存在するかどうかを判断し、このcomparison orderを使用するブール式を評価するために、比較演算子に$gtを使用しています。あなたは、このように次の例のように、あなたのパイプラインを再構築できます。

db.transactions.aggregate([ 
    { 
     "$group": { 
      "_id": { 
       "$cond": [ 
        { "$gt": [ "$account", null ] }, 
        "$account", 
        { 
         "$cond": [ 
          { "$gt": [ "$sourceAccount", null ] }, 
          "$sourceAccount", 
          "$destinationAccount" 
         ] 
        } 
       ] 
      }, 
      "count": { "$sum": 1 } 
     } 
    } 
]) 

サンプル出力

{ "_id" : ObjectId("571a0e145d29024733793cfd"), "count" : 1 } 
{ "_id" : ObjectId("571a0e145d29024733793cfe"), "count" : 2 } 
+1

はありがとうございました!それはうまく動作します!私はそのようなことをしたいと思っていましたが、私は想像することができませんでした – dimonnwc3

+0

@ dimonnwc3あなたはこの答えを受け入れなかった特別な理由はありますか? – chridam

+0

はい。それは正しい判断ではありませんでした。 sourcleeAccountまたはdestinationAccountのトランザクション "転送"の統計で1回カウントされます。しかし、私は両方の転送として、減算し、一方を他方に追加する必要があります。私は正しい決定を書き直し、後でそれを公表します。 – dimonnwc3