在MongoDB中,如果我有一个如下所示的集合,
{
"auctionId" : 22,
"startDt" : "2017-08-28T06:00:00.000Z",
"endDt" : "2017-09-04T06:00:00.000Z",
"status" : "Open",
"pickupDt" : "2017-09-07T06:00:00.000Z",
"itmLst" :
[
{
"itemId" : 1,
"location" : "Open",
"currentBid" : 13.0,
"highBidder" : 1897,
"bidCnt" : 4,
"catgegory" : "ANTIQUES"
...
如何使用聚合函数查询它以检索auctionId = 22的不同类别的计数,按itmLststategory进行分组,因此它将返回如下所示的结果集:
{
"ANTIQUES": 56,
"TOOLS": 89,
"JEWLRY": 45,
...
}
答案 0 :(得分:1)
此处的基本情况是将.aggregate()
与$unwind
一起使用,因为您需要访问数组中的值作为分组键,当然还需$group
,因为这就是您的方式&# 34;组"事情:
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
,这将允许你使用这些值作为名称键,当然还有$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,
...
}
这表明原始输出结果确实足够了,通常你想要那种"最终重塑"要在使用光标输出的代码中完成,如果你真的甚至需要重新整形,因为无论如何都返回了所需的基本数据。
答案 1 :(得分:0)
我找到了我正在寻找的答案。这个查询:
db.auctions.aggregate([
{ "$match": { "auctionId": 22 } },
{ $unwind:'$itmLst' },
{ $group:{_id:'$itmLst.catgegory', freq:{$sum:1}} },
{ $sort:{ "_id": 1 } }
]);
db.auctions.aggregate([
{ "$match": { "auctionId": 22 } },
{ $unwind:'$itmLst' },
{ $group:{_id:'$itmLst.catgegory', freq:{$sum:1}} },
{ $sort:{ "_id": 1 } }
]);
返回:
{
"_id" : "ANTIQUES",
"freq" : 9.0
}
{
"_id" : "APPLIANCES",
"freq" : 1.0
}
{
"_id" : "ARTS CRAFTS",
"freq" : 9.0
}
{
"_id" : "BOOKS MAGAZINES",
"freq" : 6.0
}
感谢Neil指出我正确的方向。