2017-09-28 110 views
5

我想通過一個MongoDB聚合查詢來計算多個字段的不同值。使用mongodb聚合的多個字段的不同計數

因此,這裏是我的數據:

{ 
    "car_type": "suv", 
    "color": "red", 
    "num_doors": 4 
}, 
{ 
    "car_type": "hatchback", 
    "color": "blue", 
    "num_doors": 4 
}, 
{ 
    "car_type": "wagon", 
    "color": "red", 
    "num_doors": 4 
} 

我想每個字段的非重複計數:

distinct_count_car_type=3 
distinct_count_color=2 
distinct_count_num_doors=1 

我能夠將多個字段,然後做一個獨特的計數,但它只能給我指望第一場。不是所有的人。 而且它也是一大組數據。

回答

1

您正在尋找的... $objectToArray的力量!

db.foo.aggregate([ 
    {$project: {x: {$objectToArray: "$$CURRENT"}}} 
    ,{$unwind: "$x"} 
    ,{$match: {"x.k": {$ne: "_id"}}} 
    ,{$group: {_id: "$x.k", y: {$addToSet: "$x.v"}}} 
    ,{$addFields: {size: {"$size":"$y"}} } 
        ]); 

這將產生:

{ "_id" : "num_doors", "y" : [ 4 ], "size" : 1 } 
{ "_id" : "color", "y" : [ "blue", "red" ], "size" : 2 } 
{ 
    "_id" : "car_type", 
    "y" : [ 
     "wagon", 
     "hatchback", 
     "suv" 
    ], 
    "size" : 3 
} 

您可以$project$addFields您認爲合適的包含或排除該組唯一值或大小。

+0

不幸的是我使用的是mongodb 3.2和$ objectToArray,我認爲根據手冊在3.4中介紹過。 – Deckard

+0

正確。我建議升級到3.4.4。 –

+0

因此,我升級了並嘗試了您的解決方案。現在我遇到的問題是我想要執行的動態字段實際上在數組中,因爲它們是從另一個集合的$ lookup中查找的。由於$查找,問題頂部的集合位於我的結果數組中。所以當我嘗試在字段上執行$ objectToArray時,我得到「$ objectToArray需要文檔輸入,找到:array」。我首先嚐試了$ arrayToObject,也許能夠在它上面調用$ objectToArray,並且我得到「$ arrayToObject需要'key'和'v'的對象鍵,發現不正確的鍵數:5。 – Deckard

4

運行下面的管道總應該給你想要的結果:

db.collection.aggregate([ 
    { 
     "$group": { 
      "_id": null, 
      "distinct_car_types": { "$addToSet": "$car_type" }, 
      "distinct_colors": { "$addToSet": "$color" }, 
      "distinct_num_doors": { "$addToSet": "$num_doors" } 
     } 
    }, 
    { 
     "$project": { 
      "distinct_count_car_type": { "$size": "$distinct_car_types" }, 
      "distinct_count_color": { "$size": "$distinct_colors" }, 
      "distinct_count_num_doors": { "$size": "$distinct_num_doors" } 
     } 
    } 
]) 
+0

不錯,而且你還可以在投影中添加'_id:0';)。 –

+0

這工作。謝謝!它減慢了一點但不是太多。我可能需要提出一個新的問題,但如果這些對象由動態數量的字段組成(這意味着我無法提前對字段名稱進行硬編碼),該怎麼辦?有沒有辦法在我的地圖中的任意數量的字段上獲得明確的計數?我該怎麼做? – Deckard

+1

@Deckard見下文。 –