Подтвердить что ты не робот

Монгодская структура агрегации | Группировать по нескольким значениям?

Я хотел бы использовать mangoDB Aggregation Framework для запуска, что в 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 : {
            ?
        }}
);

Мой инстинкт состоял в том, чтобы попытаться передать результаты во вторую группу, я знаю, что вы можете это сделать, но это не сработает, потому что первая группа уже слишком сильно уменьшает набор данных и теряется необходимый уровень детализации.

Что я хочу сделать, это использовать группы label, responseCode и 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

Где пять групп:

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

Ответ 1

ОК, поэтому решение должно указать агрегированный ключ для значения _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 }
    }}
);