O caso básico aqui é usar
.aggregate()
com $unwind
porque você precisa acessar os valores na matriz como suas chaves de agrupamento e, claro, $group
porque é assim que você "agrupa" as coisas:db.collection.aggregate([
{ "$match": { "auctionId": 22 } },
{ "$unwind": "$itmLst" },
{ "$group": {
"_id": "$itmLst.category",
"count": { "$sum": 1 }
}}
])
Isso lhe dará uma saída como:
{ "_id": "ANTIQUES", "count": 56 }
{ "_id": "TOOLS", "count": 89 }
{ "_id": "JEWLRY", "count": 45 }
Agora você realmente deve aprender a conviver com isso, porque uma "lista" no formato de cursor padrão é uma coisa boa que é naturalmente iterável. Além disso, as chaves nomeadas IMHO não se prestam naturalmente à apresentação de dados e geralmente você deseja uma propriedade comum em uma lista iterável.
Se você realmente pretende usar a saída de chaves nomeadas singulares, precisará do MongoDB 3.4.4 ou superior para ter acesso a
$arrayToObject
que permitirá que você use os valores como os nomes das chaves e, claro, $replaceRoot
para usar essa saída de expressão como o novo documento para produzir: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"
}
}}
])
Ou, se você não tiver essa opção, deverá converter a saída do cursor em 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 fundem em um único objeto com chaves nomeadas da saída de agregação original:
{
"ANTIQUES": 56,
"TOOLS": 89,
"JEWLRY": 45,
...
}
E isso mostra que o resultado da saída original foi realmente suficiente e que normalmente você deseja que esse tipo de "remodelagem final" seja feito no código que usa a saída do cursor, se você realmente precisar dessa reformulação desde o básico os dados necessários foram retornados de qualquer maneira.