web-dev-qa-db-ja.com

Mongodb集計フレームワーク|複数の値でグループ化しますか?

MongoDBの集約フレームワークを使用して、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番目のグループにパイプすることを試みることでした。私はこれを実行できることを知っていますが、最初のグループがすでにデータセットを減らしすぎており、必要な詳細レベルが失われているため、うまくいきません。

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

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"}
26
Oliver Lloyd

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 }
    }}
);
37
Oliver Lloyd