2017-09-05 22 views
0

在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,由itmLst.category分组,所以它会返回的结果集是这样的:

{ 
    "ANTIQUES": 56, 
    "TOOLS": 89, 
    "JEWLRY": 45, 
    ... 
} 
+0

你有什么试过[尼克](https://stackoverflow.com/users/5509126/nick-kicher) –

回答

0

我找到了我正在寻找的答案。这个查询:

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 
} 

谢谢尼尔指着我在正确的方向,但。

1

这里的基本情况是因为你需要访问值使用.aggregate()$unwind该数组作为您的分组键和o ˚F当然$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,这将允许您使用这些值作为键的名称,并且当然$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, 
    ... 
} 

而这正好说明,原来的输出结果真是如此,这通常是你想要的那种“最后整形”来在使用游标输出的代码中完成,如果你确实需要重新整形,因为无论如何都需要返回基本数据。

+0

谢谢你的回应尼尔,我很好你的第一个解决方案的输出,但是当我尝试一下,它返回0条记录。你知道这是为什么吗?我在做db.auctions.aggregate(“$ match”:{“auctionId”:22}}, {“$ unwind”:“$ itmList”}, {“$ group”:{ “_id “:”$ itmList.category“, ”count“:{”$ sum“:1} }} –

+0

@NickKicher因为您的项目数组似乎被命名为**'itmLst' **而不是' itmList' –

相关问题