El caso básico aquí es usar .aggregate()
con $unwind
porque necesita acceder a los valores de la matriz como claves de agrupación y, por supuesto, $group
porque así es como "agrupas" las cosas:
db.collection.aggregate([
{ "$match": { "auctionId": 22 } },
{ "$unwind": "$itmLst" },
{ "$group": {
"_id": "$itmLst.category",
"count": { "$sum": 1 }
}}
])
Esto le dará una salida como:
{ "_id": "ANTIQUES", "count": 56 }
{ "_id": "TOOLS", "count": 89 }
{ "_id": "JEWLRY", "count": 45 }
Ahora realmente debería aprender a vivir con eso, porque una "lista" en el formato de cursor predeterminado es algo bueno que es naturalmente iterable. Además, en mi humilde opinión, las claves con nombre no se prestan naturalmente a la presentación de datos y, por lo general, desea una propiedad común en una lista iterable.
Si realmente tiene la intención de usar la salida de claves con nombre singular, entonces necesitará MongoDB 3.4.4 o superior para tener acceso a $arrayToObject
eso le permitirá usar los valores como los nombres de las claves y, por supuesto, $replaceRoot
para usar esa salida de expresión como el nuevo documento a producir:
db.collection.aggregate([
{ "$match": { "auctionId": 22 } },
{ "$unwind": "$itmLst" },
{ "$group": {
"_id": "$itmLst.category",
"count": { "$sum": 1 }
}},
{ "$group": {
"_id": null,
"data": { "$push": { "k": "$_id", "v": "$count" } }
}},
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": "$data"
}
}}
])
O si no tiene esa opción, entonces debería convertir la salida del cursor en código:
db.collection.aggregate([
{ "$match": { "auctionId": 22 } },
{ "$unwind": "$itmLst" },
{ "$group": {
"_id": "$itmLst.category",
"count": { "$sum": 1 }
}}
]).toArray().reduce((acc,curr) =>
Object.assign(acc,{ [curr._id]: curr.count }),
{}
)
Ambos se fusionan en un solo objeto con claves nombradas de la salida de agregación original:
{
"ANTIQUES": 56,
"TOOLS": 89,
"JEWLRY": 45,
...
}
Y eso demuestra que el resultado de la salida original fue realmente suficiente y que, por lo general, desea que se realice ese tipo de "remodelación final" en el código que usa la salida del cursor, si es que realmente necesita esa remodelación desde el principio. los datos necesarios se devolvieron de todos modos.