这里的基本情况是使用.aggregate() https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/ with $unwind https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/因为您需要访问数组中的值作为分组键,当然$group https://docs.mongodb.com/manual/reference/operator/aggregation/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 }
现在你真的应该学会忍受这一点,因为默认光标格式的“列表”是一件好事,它自然是可迭代的。另外,恕我直言,命名键本身并不适合数据表示,并且您通常需要可迭代列表中的公共属性。
如果您确实打算使用单一命名键输出,那么您将需要 MongoDB 3.4.4 或更高版本才能访问$arrayToObject https://docs.mongodb.com/manual/reference/operator/aggregation/arrayToObject/这将允许您使用值作为键的名称,当然$replaceRoot https://docs.mongodb.com/manual/reference/operator/aggregation/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,
...
}
这表明原始输出结果确实足够了,并且通常您希望在使用光标输出的代码中完成这种“最终重塑”,如果您真的需要这种重塑,因为基本的无论如何,所需的数据已返回。