relacionar - Marco de Agregación de Mongodb | ¿Grupo sobre valores múltiples?
mongodb documentos relacionados (1)
Me gustaría usar el Framework de agregación de mongoDB para ejecutar lo que en SQL se parecería un poco a esto:
SELECT SUM(A), B, C from myTable GROUP BY B, C;
El estado de los documentos:
Puede especificar un único campo de los documentos en la canalización, un valor calculado previamente o una clave agregada compuesta por varios campos entrantes.
Pero no está claro qué es en realidad una ''clave agregada hecha de varios campos entrantes''.
Mi conjunto de datos es un poco así:
[{ "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"}]
Mi consulta se ve así:
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 : {
?
}}
);
Mi instinto fue tratar de canalizar los resultados a través de un segundo grupo, sé que puedes hacer esto pero no funcionará porque el primer grupo ya reduce demasiado el conjunto de datos y se pierde el nivel de detalle requerido.
Lo que quiero hacer es agrupar usando label
, responseCode
y success
y obtener la suma del valor del resultado. Debería verse un poco como:
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
Donde hay cinco grupos:
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"}
OK, entonces la solución es especificar una clave agregada para el valor _id. Esto está documentado here como:
Puede especificar un único campo de los documentos en la canalización, un valor calculado previamente o una clave agregada compuesta por varios campos entrantes.
Pero en realidad no define el formato para una clave agregada. Al leer la documentación anterior here , vi que el método collection.group anterior podía tomar múltiples campos y que se usa la misma estructura en el nuevo framework.
Entonces, para agrupar en múltiples campos, puede usar _id : { success:''$success'', responseCode:''$responseCode'', label:''$label''}
Como en:
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 }
}}
);