Necesito obtener los N elementos principales de una consulta y agrupar todos los demás elementos (no en N principales) en un elemento adicional.
Por ejemplo, considerando una colección con los siguientes documentos:
{user: "Ana", post: "A" }, {user: "Ana", post: "B" }, {user: "Ana", post: "C" }, {user: "Ana", post: "D" }, {user: "Bruce", post: "E" }, {user: "Bruce", post: "F" }, {user: "Bruce", post: "G" }, {user: "Cami", post: "H" }, {user: "Cami", post: "I" }, {user: "John", post: "J" }, {user: "Peter", post: "K" }, {user: "Helena", post: "L" }Espero obtener los 2 usuarios que más contribuyen y agregar todos los demás en un elemento de salida adicional. Por ejemplo:
{user: "Ana", count: 4}, {user: "Bruce", count: 3}, {user: "All others guys", count: 5}Ahora estoy usando la función "agregar":
db.MyTest.aggregate( [ { $group: { "_id": "$user", count: { $sum: 1 } } }, { $sort: { count: -1, userName: 1 } } ] );No tengo idea de cómo tratar el elemento "Todos los demás". Mi función está devolviendo los siguientes resultados:
{_id: "Ana", count: 4}, {_id: "Bruce", count: 3}, {_id: "Cami", count: 2}, {_id: "John", count: 1}, {_id: "Peter", count: 1}, {_id: "Helena", count: 1}¿Alguna idea de cómo hacer esto directamente en mongo con una sola consulta?
PD: Estoy usando Mongo 3.2.11.
Después de ordenar las estadísticas, puede enviar las estadísticas de todos los usuarios a la matriz y luego tomar los elementos requeridos por índice de esa matriz y dividir todos los demás elementos para agregar sus estadísticas más tarde:
db.users.aggregate([ {$group: {_id:"$user", count:{$sum:1}}}, {$sort: {count:-1}}, // Split stats into first, second and others {$group: {_id:1, users:{$push:{user:"$_id", count:"$count"}}}}, {$project: { first : {$arrayElemAt: ["$users", 0]}, second: {$arrayElemAt: ["$users", 1]}, others: {$slice:["$users", 2, {$size: "$users"}]} } }, // Calculate count for all other guys {$project: { stats: [ "$first", "$second", { user: "All other guys", count: {$sum: "$others.count"} } ] } }, // Bring embeded documents to top level {$unwind: "$stats"}, {$project: { _id:0, user: "$stats.user", count: "$stats.count" }} ])Producción:
{ "user" : "Ana", "count" : 4 }, { "user" : "Bruce", "count" : 3 }, { "user" : "All other guys", "count" : 5 }Nota: el código funcionará incluso si tiene cero o un solo usuario en la base de datos. Pero en el segundo caso, obtendrá un documento vacío para las estadísticas del segundo usuario más publicable. Lo cual es bastante justo.