Tengo documentos como ese en mi base de datos mongo:
{ {"_id" : NumberLong(50), "offerId" : NumberLong(88), "isInTryPeriod" : false, "state" : { "currentState" : "INACTIVE", "oldState" : "INACTIVE" }, ...... ...... ...... }
Y quiero agruparlos en "offerId", pero también quiero ver el número de recuento isInTryPeriod (para verdadero y falso) y estado actual (activo, inactivo, etc.) en estados específicos como los siguientes:
{{ _id: offerId states: { isInTryperiodCountForThatOfferId: X activeForThatOfferId: X inactiveForThatOfferId: X }, { _id: offerId states: { isInTryperiodCountForThatOfferId: X activeForThatOfferId: X inactiveForThatOfferId: X }}
Lo que intenté es escribir dos consultas para ellos, funcionan por separado, pero quiero componerlos.
Para obtener el recuento del campo sate.currentState
db.subscriptions.aggregate( { $group: { _id: { offerId: "$offerId", state: "$state.currentState" }, "state": { "$push": "$state.currentState" }, "total": { "$sum": 1 } } }, { $group: { _id: { offerId: "$_id.offerId" }, state: { $addToSet: { state: "$_id.state", sum:"$total" } } } } );
Para obtener el recuento del campo isInTrpPreiod
db.subscriptions.aggregate([ { $match : {isInTryPeriod : true} }, { $group: { _id: { offerId: "$offerId", "isInTryPeriod" : "$isInTryPeriod"}, "isInTryPeriod": { "$push": "$isInTryPeriod" }, "total": { "$sum": 1 } } }, { $group: { _id: "$_id.offerId", isInTryPeriod: { $addToSet: { isInTryPeriod: "$_id.isInTryPeriod", sum:"$total" } } } } ]);
Debería poder agrupar por offerId
de oferta y usar $cond para sumar campos en función de una condición.
db.getCollection('subscriptions').aggregate([ { $group: { _id: { offerId : "$offerId" }, "totalActiveState": { "$sum": { "$cond": [ { "$eq": ["$state.currentState", "ACTIVE"] }, 1, 0 ] } }, "totalInactiveState": { "$sum": { "$cond": [ { "$eq": ["$state.currentState", "INACTIVE"] }, 1, 0 ] } }, "totalIsInTryPeriod": { "$sum": { "$cond": [ { "$eq": ["$isInTryPeriod", true] }, 1, 0 ] } } } } ])
Esto devolverá algo como lo siguiente:
[ { "_id" : { "offerId" : 77.0 }, "totalActiveState" : 1.0, "totalInactiveState" : 0.0, "totalIsInTryPeriod" : 1.0 }, { "_id" : { "offerId" : 88.0 }, "totalActiveState" : 1.0, "totalInactiveState" : 2.0, "totalIsInTryPeriod" : 2.0 } ]
No estoy seguro sobre el rendimiento, pero debería darte los resultados.