2012-07-10 8 views
26

私は少しのようになりますSQLで何を実行するのにMongoDBの集約フレームワークを使用したい:Mongodb集約フレームワーク|複数の値をグループ化する?

SELECT SUM(A), B, C from myTable GROUP BY B, C; 

ドキュメントの状態:

あなたがパイプラインの文書から単一のフィールドを指定することができます、以前に計算された値、またはいくつかの受信フィールドから構成された集約キーです。

しかし、実際にはいくつかの受信フィールドから集計されたキーが実際に何であるかは不明です。

私のデータセットは少し、このようなものです:

[{ "timeStamp" : 1341834988666, "label" : "sharon", "responseCode" : "200", "value" : 10, "success" : "true"}, 
{ "timeStamp" : 1341834988676, "label" : "paul", "responseCode" : "200", "value" : 60, "success" : "true"}, 
{ "timeStamp" : 1341834988686, "label" : "paul", "responseCode" : "404", "value" : 15, "success" : "true"}, 
{ "timeStamp" : 1341834988696, "label" : "sharon", "responseCode" : "200", "value" : 35, "success" : "false"}, 
{ "timeStamp" : 1341834988166, "label" : "paul", "responseCode" : "200", "value" : 40, "success" : "true"}, 
{ "timeStamp" : 1341834988266, "label" : "paul", "responseCode" : "404", "value" : 99, "success" : "false"}] 

私のクエリは次のようになります。

resultsCollection.aggregate(
    { $match : { testid : testid} }, 
    { $skip : alreadyRead }, 
    { $project : { 
      timeStamp : 1 , 
      label : 1, 
      responseCode : 1 , 
      value : 1, 
      success : 1 
     }}, 
    { $group : { 
      _id : "$label", 
      max_timeStamp : { $timeStamp : 1 }, 
      count_responseCode : { $sum : 1 }, 
      avg_value : { $sum : "$value" }, 
      count_success : { $sum : 1 } 
     }}, 
    { $group : { 
      ? 
     }} 
); 

私の本能は、第二のグループに至るパイプに結果を試してみました、私はあなたを知っていますこれを行うことはできますが、最初のグループがすでにデータセットを減らしており、必要な詳細レベルが失われているため、機能しません。

私がしたいことは、labelresponseCodeおよびsuccessを使用してグループ化し、結果からの合計を得ることです。 5つのグループがある

label | code | success | sum_of_values | count 
sharon | 200 | true |  10  | 1 
sharon | 200 | false |  35  | 1 
paul | 200 | true |  100  | 2 
paul | 404 | true |  15  | 1 
paul | 404 | false |  99  | 1 

:それは少しのようになります

1. { "timeStamp" : 1341834988666, "label" : "sharon", "responseCode" : "200", "value" : 10, "success" : "true"} 

2. { "timeStamp" : 1341834988696, "label" : "sharon", "responseCode" : "200", "value" : 35, "success" : "false"} 

3. { "timeStamp" : 1341834988676, "label" : "paul", "responseCode" : "200", "value" : 60, "success" : "true"} 
    { "timeStamp" : 1341834988166, "label" : "paul", "responseCode" : "200", "value" : 40, "success" : "true"} 

4. { "timeStamp" : 1341834988686, "label" : "paul", "responseCode" : "404", "value" : 15, "success" : "true"} 

5. { "timeStamp" : 1341834988266, "label" : "paul", "responseCode" : "404", "value" : 99, "success" : "false"} 

答えて

37

OKが、そうソリューションは、_id値の集計キーを指定することです。

あなたはパイプライン、以前に計算した値、またはいくつかの着信フィールドから構成された集計キーで文書から単一のフィールドを指定することができます。これはhereのように記載されています。

しかし、実際には集約キーの形式は定義されていません。以前のドキュメントを読むhere以前のcollection.groupメソッドは複数のフィールドを取ることができ、同じフレームワークが新しいフレームワークで使用されていることがわかりました。

ので、複数のフィールドを超えるグループに、あなたは同様に_id : { success:'$success', responseCode:'$responseCode', label:'$label'}

を使用することができます:あなたの$プロジェクトの目的が何であるかを

resultsCollection.aggregate(
{ $match : { testid : testid} }, 
{ $skip : alreadyRead }, 
{ $project : { 
     timeStamp : 1 , 
     label : 1, 
     responseCode : 1 , 
     value : 1, 
     success : 1 
    }}, 
{ $group : { 
     _id : { success:'$success', responseCode:'$responseCode', label:'$label'}, 
     max_timeStamp : { $timeStamp : 1 }, 
     count_responseCode : { $sum : 1 }, 
     avg_value : { $sum : "$value" }, 
     count_success : { $sum : 1 } 
    }} 
); 
+1

?はるかに大きな元の文書ですか?また、それを前に並べ替えることなくスキップすることはあまり意味がありません。 avg_valueが必要な場合はなぜ$ avgを使用しないのですか?あなたがsum_valueを呼び出さない理由をまとめたいのですか?また、count_successとcount_responseCodeは同じになるでしょう。両方が必要な理由は不明です。 –

+9

注:2.2.0-rc1から、_id:{success:1、responseCode:1、label:1}は複数のフィールドでグループ化されています。_id:{success: "$ success"、responseCode: "$ responseCode"、ラベル: "$ label"}。 https://groups.google.com/forum/?fromgroups#!topic/mongodb-user/1cYch580h0w – Richard

+1

回答は@リチャードに従って固定されています。 –

関連する問題