Základním případem je použití .aggregate()
s $unwind
protože potřebujete přístup k hodnotám v poli jako vaše seskupovací klíče a samozřejmě $group
protože tak věci „seskupujete“:
db.collection.aggregate([
{ "$match": { "auctionId": 22 } },
{ "$unwind": "$itmLst" },
{ "$group": {
"_id": "$itmLst.category",
"count": { "$sum": 1 }
}}
])
To vám dá výstup jako:
{ "_id": "ANTIQUES", "count": 56 }
{ "_id": "TOOLS", "count": 89 }
{ "_id": "JEWLRY", "count": 45 }
Nyní byste se s tím měli opravdu naučit žít, protože „seznam“ ve výchozím formátu kurzoru je dobrá věc, která je přirozeně iterovatelná. Také IMHO pojmenované klíče se přirozeně nehodí k prezentaci dat a obecně chcete mít společnou vlastnost v iterovatelném seznamu.
Pokud opravdu máte v úmyslu používat výstup singulárních pojmenovaných klíčů, pak budete buď potřebovat MongoDB 3.4.4 nebo vyšší, abyste měli přístup k $arrayToObject
které vám umožní použít hodnoty jako názvy klíčů a samozřejmě $replaceRoot
za účelem použití tohoto výrazového výstupu jako nového dokumentu k vytvoření:
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"
}
}}
])
Nebo pokud tuto možnost nemáte, měli byste místo toho konvertovat výstup kurzoru v kódu:
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 }),
{}
)
Oba se sloučí do jednoho objektu s pojmenovanými klíči z původního výstupu agregace:
{
"ANTIQUES": 56,
"TOOLS": 89,
"JEWLRY": 45,
...
}
A to ukazuje, že původní výsledek výstupu byl skutečně dostačující a že obvykle chcete, aby se takový druh „konečné změny tvaru“ provedl v kódu, který používá výstup kurzoru, pokud toto přetvoření vůbec potřebujete od základního potřebná data byla stejně vrácena.