ここでの基本的なケースは、 .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の名前付きキーは、データの表示には自然に役立ちません。通常、反復可能なリストに共通のプロパティが必要です。
単一の名前付きキー出力を使用することに本当に熱心な場合は、 $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,
...
}
これは、元の出力結果が本当に十分であり、基本的なものから本当に再形成が必要な場合は、通常、カーソル出力を使用するコードでその種の「最終的な再形成」を実行する必要があることを示しています。とにかく必要なデータが返されました。