mongoDB的管道是個好東西,它能夠將不少操做批處理實現,即將多個命令放入一個管道,而後去順序的執行它們,今天我要說的是,利用管道中的分組來實現實現中的ditinct+group的效果,即先對一個元素去重,而後即一個字段進行分組,如你的userinfoID,它對應多個planID,而咱們在planID在表中確定是重複的,這時,咱們須要統計userinfo對應多個種planID,這時問題就來了,尤於planID是重複的,因此分組的結果多是錯誤的,它並非真正意思上的(planID種類),正確的做法應該是先對planID去重複,而後再根據userinfoID去做分組,而這個在大多數的數據庫裏,是經過多重分組實現的,即選對userinfoID和planID進行分組,而後對結果進行userinfoID的分組,這種就把多於的planID去掉了。數據庫
具體做法:數組
//多分組(group+distinct) db.M_User_Footprints.aggregate([ { $group: { _id: { UserInfoID: "$UserInfoID", ObjID: "$PlayVideo.ObjID" } } }, { $group: { _id: "$_id.UserInfoID", count: { $sum: 1 } } }, { $sort: { "_id": 1 } } ]);
注意,這裏的第二個分組用的是第一個分組的_id,因此加上了$_id,這表示使用上面group的數據源來做爲第二個分組的鍵。ide
而若是隻是單個分組,就很容易實現了,也看一下代碼this
//單分組 db.M_User_Footprints.aggregate([ { $group: { _id: "$UserInfoID", result: { $sum: 1 } } } ])
從上面兩段代碼咱們能夠看到,分組鍵必須用_id,分組的結果名稱能夠本身定義,{$sum:1}每次自加1。it
下面使用map...reduce也能夠實現分組的功能io
db.runCommand({ mapreduce: "M_User_Footprints", map: function Map() { emit( { "UserInfoID": this.UserInfoID, "ObjID": this.PlayVideo.ObjID } , { count: 1 } ); }, reduce: function Reduce(key, values) { total = 0;//定義一個變量total , values是一個數組 for (var i in values) { total += values[i].count } return { "count": total }; }, finalize: function Finalize(key, reduced) { return reduced; }, out: { inline: 1 } });