27

mongoDBのAggregationFrameworkを使用して、SQLで次のように表示されるものを実行したいと思います。

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 : {
            ?
        }}
);

私の本能は、結果を2番目のグループにパイプすることでした。これは可能ですが、最初のグループはすでにデータセットを減らしすぎて、必要な詳細レベルが失われているため、機能しません。

私がやりたいのはlabelresponseCodeを使用してグループ化しsuccess、結果から値の合計を取得することです。次のようになります。

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

5つのグループがある場合:

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"}
4

1 に答える 1

38

解決策は、_id 値に集計キーを指定することです。これは、次のようにここに文書化されています。

パイプライン内のドキュメントから単一のフィールド、以前に計算された値、または複数の受信フィールドから作成された集計キーを指定できます。

ただし、実際には集計キーの形式は定義されていません。ここで以前のドキュメントを読むと、以前の 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 }
    }}
);
于 2012-07-10T22:33:37.363 に答える