Основният случай тук е да използвате .aggregate()
с $unwind
защото имате нужда от достъп до стойностите в масива като ваши ключове за групиране и разбира се $group
защото така „групирате“ нещата:
db.collection.aggregate([
{ "$match": { "auctionId": 22 } },
{ "$unwind": "$itmLst" },
{ "$group": {
"_id": "$itmLst.category",
"count": { "$sum": 1 }
}}
])
Това ще ви даде резултат като:
{ "_id": "ANTIQUES", "count": 56 }
{ "_id": "TOOLS", "count": 89 }
{ "_id": "JEWLRY", "count": 45 }
Сега наистина трябва да се научите да живеете с това, защото "списък" във формата на курсора по подразбиране е добро нещо, което естествено може да се повтаря. Също така IMHO именуваните ключове не се поддават естествено на представяне на данни и обикновено искате общо свойство в итерируем списък.
Ако наистина възнамерявате да използвате изхода с единствени именувани ключове, тогава или ще ви трябва MongoDB 3.4.4 или по-нова версия, за да имате достъп до $arrayToObject
което ще ви позволи да използвате стойностите като имена на ключове и разбира се $replaceRoot
за да използвате този изходен израз като нов документ за създаване:
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"
}
}}
])
Или ако нямате тази опция, тогава вместо това трябва да конвертирате изхода на курсора в код:
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 }),
{}
)
И двата се сливат в един обект с наименувани ключове от оригиналния изход за агрегиране:
{
"ANTIQUES": 56,
"TOOLS": 89,
"JEWLRY": 45,
...
}
И това показва, че първоначалният изходен резултат наистина е достатъчен и че обикновено искате този вид "окончателно преоформяне" да бъде направено в кода, който използва изхода на курсора, ако наистина изобщо имате нужда от това преоформяне, тъй като основното така или иначе необходимите данни бяха върнати.