Tengo colecciones de documentos como a continuación:
{ "_id" : ObjectId("55d4410544c96d6f6578f893"), "executionProject" : "Project1", "suiteList" : [ { "suiteStatus" : "PASS", } ], "runEndTime" : ISODate("2015-08-19T08:40:47.049Z"), "runStartTime" : ISODate("2015-08-19T08:40:37.621Z"), "runStatus" : "PASS", "__v" : 1 } { "_id" : ObjectId("55d44eb4c0422e7b8bffe76b"), "executionProject" : "Project1", "suiteList" : [ { "suiteStatus" : "PASS", } ], "runEndTime" : ISODate("2015-08-19T09:39:13.528Z"), "runStartTime" : ISODate("2015-08-19T09:39:00.406Z"), "runStatus" : "PASS", "__v" : 1 } { "_id" : ObjectId("55d44f0bc0422e7b8bffe76f"), "executionProject" : "Project1", "suiteList" : [ { "suiteStatus" : "FAIL", } ], "runEndTime" : ISODate("2015-08-19T09:46:31.108Z"), "runStartTime" : ISODate("2015-08-19T09:40:27.377Z"), "runStatus" : "PASS", "__v" : 1 } { "_id" : ObjectId("55d463d0c0422e7b8bffe789"), "executionProject" : "Project2", "suiteList" : [ { "suiteStatus" : "FAIL" }, { "suiteStatus" : "PASS" } ], "runEndTime" : ISODate("2015-08-19T11:09:52.537Z"), "runStartTime" : ISODate("2015-08-19T11:09:04.539Z"), "runStatus" : "FAIL", "__v" : 1 } { "_id" : ObjectId("55d464ebc0422e7b8bffe7c2"), "executionProject" : "Project3", "suiteList" : [ { "suiteStatus" : "FAIL" } ], "runEndTime" : ISODate("2015-08-19T11:18:41.460Z"), "runStartTime" : ISODate("2015-08-19T11:13:47.268Z"), "runStatus" : "FAIL", "__v" : 10 }
Y estoy esperando la salida de la siguiente manera:
[ { "executionProject": "Project1", "suite-pass": 0, "suite-fail": 1, "runEndTime": ISODate("2015-08-19T09:46:31.108Z") }, { "executionProject": "Project2", "suite-pass": 1, "suite-fail": 1, "runEndTime": ISODate("2015-08-19T11:09:52.537Z") }, { "executionProject": "Project3", "suite-pass": 0, "suite-fail": 1, "runEndTime": ISODate("2015-08-19T11:18:41.460Z") }, ]
Quiero agrupar por proyecto y orden por runEndTime y mostrar los conteos de pasadas y fallas de suiteList.
Sé cómo obtener los recuentos de pases y fallos de todas las ejecuciones, pero no estoy seguro de cómo puedo agrupar y ordenar. Por favor ayuda
El marco de agregación con el operador $cond
parece ser lo que está buscando:
Model.aggregate([ { "$unwind": "$suiteList" }, { "$group": { "_id": "$executionProject", "suite-pass": { "$sum": { "$cond": [ { "$eq": [ "$suiteList.suiteStatus", "PASS" ] }, 1, 0 ] } }, "suite-fail": { "$sum": { "$cond": [ { "$eq": [ "$suiteList.suiteStatus", "FAIL" ] }, 1, 0 ] } }, "runEndTime": { "$max": "$runEndTime" } }}, { "$sort": { "runEndTime": 1 }} ],function(err,result) { });
Esto prueba condicionalmente los valores para “PASS” o “FAIL” y los devuelve al acumulador de $sum
debajo de $group
. De la misma manera, toma el valor $max
para la fecha relevante por documentos agrupados.
Lo último es solo $sort
por esa fecha
Si la “suiteList” en realidad solo contendrá un “PASS” y un “FAIL” al máximo, entonces es probable que pueda escapar sin siquiera usar $unwind
en la matriz:
Model.aggregate( [ { "$group": { "_id": "$executionProject", "suite-pass": { "$sum": { "$cond": [ { "$anyElementTrue": { "$map": { "input": "$suiteList", "as": "suite", "in": { "$eq": [ "$$suite.suiteStatus", "PASS" ] } } }}, 1, 0 ] } }, "suite-fail": { "$sum": { "$cond": [ { "$anyElementTrue": { "$map": { "input": "$suiteList", "as": "suite", "in": { "$eq": [ "$$suite.suiteStatus", "FAIL" ] } } }}, 1, 0 ] } }, "runEndTime": { "$max": "$runEndTime" } }}, { "$sort": { "runEndTime": 1 }} ], function(err,results) { } )
El $map
y $anyElementTrue
allí pueden probar de forma similar las condiciones en la matriz que coinciden en el lugar en el que se deben contar. Por lo tanto, si el “número de coincidencias” por documento no importa, entonces esto está bien.
En sus datos aquí que cumplen esas condiciones, ambos producen el mismo resultado:
{ "_id" : "Project1", "suite-pass" : 2, "suite-fail" : 1, "runEndTime" : ISODate("2015-08-19T09:46:31.108Z") } { "_id" : "Project2", "suite-pass" : 1, "suite-fail" : 1, "runEndTime" : ISODate("2015-08-19T11:09:52.537Z") } { "_id" : "Project3", "suite-pass" : 0, "suite-fail" : 1, "runEndTime" : ISODate("2015-08-19T11:18:41.460Z") }
Para obtener los “últimos” artículos, simplemente $sort
primero y reemplaza los sumdores de $sum
por el $last
acumulador de $last
:
Model.aggregate( [ { "$sort": { "runEndTime": 1 } }, { "$group": { "_id": "$executionProject", "suite-pass": { "$last": { "$cond": [ { "$anyElementTrue": { "$map": { "input": "$suiteList", "as": "suite", "in": { "$eq": [ "$$suite.suiteStatus", "PASS" ] } } }}, 1, 0 ] } }, "suite-fail": { "$last": { "$cond": [ { "$anyElementTrue": { "$map": { "input": "$suiteList", "as": "suite", "in": { "$eq": [ "$$suite.suiteStatus", "FAIL" ] } } }}, 1, 0 ] } }, "runEndTime": { "$last": "$runEndTime" } }}, { "$sort": { "runEndTime": 1 } } ], function(err,results) { } );
Lo que produce:
{ "_id" : "Project1", "suite-pass" : 0, "suite-fail" : 1, "runEndTime" : ISODate("2015-08-19T09:46:31.108Z") } { "_id" : "Project2", "suite-pass" : 1, "suite-fail" : 1, "runEndTime" : ISODate("2015-08-19T11:09:52.537Z") } { "_id" : "Project3", "suite-pass" : 0, "suite-fail" : 1, "runEndTime" : ISODate("2015-08-19T11:18:41.460Z") }