¿Hay alguna manera de calcular la mediana utilizando el marco de agregación de MongoDB?
Solución del problema
Si bien la respuesta de maxiplay no es precisa, me guió en la dirección correcta. El problema con la solución dada es que solo funciona cuando el número de registros es par. Porque para un número impar de registros, simplemente se necesita tomar el valor en el punto medio sin tener que calcular un promedio.
Así es como lo hice funcionar.
db.collection.aggregate([
{ "$match": { "processingStatus": "Completed" } },
{ "$sort": { "value": 1 } },
{
"$group": {
"_id": "$userId",
"valueArray": {
"$push": "$value"
}
}
},
{
"$project": {
"_id": 0,
"userId": "$_id",
"valueArray": 1,
"size": { "$size": ["$valueArray"] }
}
},
{
"$project": {
"userId": 1,
"valueArray": 1,
"isEvenLength": { "$eq": [{ "$mod": ["$size", 2] }, 0 ] },
"middlePoint": { "$trunc": { "$divide": ["$size", 2] } }
}
},
{
"$project": {
"userId": 1,
"valueArray": 1,
"isEvenLength": 1,
"middlePoint": 1,
"beginMiddle": { "$subtract": [ "$middlePoint", 1] },
"endMiddle": "$middlePoint"
}
},
{
"$project": {
"userId": 1,
"valueArray": 1,
"middlePoint": 1,
"beginMiddle": 1,
"beginValue": { "$arrayElemAt": ["$valueArray", "$beginMiddle"] },
"endValue": { "$arrayElemAt": ["$valueArray", "$endMiddle"] },
"isEvenLength": 1
}
},
{
"$project": {
"userId": 1,
"valueArray": 1,
"middlePoint": 1,
"beginMiddle": 1,
"beginValue": 1,
"endValue": 1,
"middleSum": { "$add": ["$beginValue", "$endValue"] },
"isEvenLength": 1
}
},
{
"$project": {
"userId": 1,
"valueArray": 1,
"median": {
"$cond": {
if: "$isEvenLength",
then: { "$divide": ["$middleSum", 2] },
else: { "$arrayElemAt": ["$valueArray", "$middlePoint"] }
}
}
}
}
])
No hay comentarios.:
Publicar un comentario