2017-09-05 20 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' –

相關問題