MongoDB學習筆記(ji)~管道中的(de)分組實現group+distinct
mongoDB的(de)(de)管(guan)道(dao)是個(ge)(ge)好東西(xi),它(ta)可(ke)以將很多(duo)(duo)操作批處理實(shi)(shi)現,即(ji)(ji)將多(duo)(duo)個(ge)(ge)命令(ling)放入一個(ge)(ge)管(guan)道(dao),然后(hou)去(qu)(qu)順序的(de)(de)執行它(ta)們(men),今天我要說的(de)(de)是,利用管(guan)道(dao)中(zhong)(zhong)的(de)(de)分(fen)(fen)(fen)組(zu)(zu)(zu)來(lai)實(shi)(shi)現實(shi)(shi)現中(zhong)(zhong)的(de)(de)ditinct+group的(de)(de)效果(guo),即(ji)(ji)先(xian)(xian)對(dui)一個(ge)(ge)元素去(qu)(qu)重,然后(hou)即(ji)(ji)一個(ge)(ge)字段進(jin)(jin)行分(fen)(fen)(fen)組(zu)(zu)(zu),如你(ni)的(de)(de)userinfoID,它(ta)對(dui)應(ying)多(duo)(duo)個(ge)(ge)planID,而(er)我們(men)在planID在表中(zhong)(zhong)肯定(ding)是重復(fu)的(de)(de),這(zhe)時,我們(men)需要統計userinfo對(dui)應(ying)多(duo)(duo)個(ge)(ge)種(zhong)(zhong)planID,這(zhe)時問題就(jiu)來(lai)了(le),尤于(yu)planID是重復(fu)的(de)(de),所(suo)以分(fen)(fen)(fen)組(zu)(zu)(zu)的(de)(de)結果(guo)可(ke)能是錯誤的(de)(de),它(ta)并不(bu)是真正意思上的(de)(de)(planID種(zhong)(zhong)類),正確的(de)(de)作法應(ying)該是先(xian)(xian)對(dui)planID去(qu)(qu)重復(fu),然后(hou)再根據(ju)userinfoID去(qu)(qu)作分(fen)(fen)(fen)組(zu)(zu)(zu),而(er)這(zhe)個(ge)(ge)在大(da)多(duo)(duo)數的(de)(de)數據(ju)庫(ku)里,是通過多(duo)(duo)重分(fen)(fen)(fen)組(zu)(zu)(zu)實(shi)(shi)現的(de)(de),即(ji)(ji)選對(dui)userinfoID和(he)planID進(jin)(jin)行分(fen)(fen)(fen)組(zu)(zu)(zu),然后(hou)對(dui)結果(guo)進(jin)(jin)行userinfoID的(de)(de)分(fen)(fen)(fen)組(zu)(zu)(zu),這(zhe)種(zhong)(zhong)就(jiu)把多(duo)(duo)于(yu)的(de)(de)planID去(qu)(qu)掉了(le)。
具體作法:
//多(duo)分組(group+distinct) db.M_User_Footprints.aggregate([ { $group: { _id: { UserInfoID: "$UserInfoID", ObjID: "$PlayVideo.ObjID" } } }, { $group: { _id: "$_id.UserInfoID", count: { $sum: 1 } } }, { $sort: { "_id": 1 } } ]);
注意,這里的第二個分(fen)組用的是(shi)第一個分(fen)組的_id,所以加上(shang)了(le)$_id,這表示使用上(shang)面(mian)group的數據源(yuan)來作為(wei)第二個分(fen)組的鍵(jian)。
而如果(guo)只(zhi)是單個分組,就很(hen)容易(yi)實現了,也看一下代碼
//單分組 db.M_User_Footprints.aggregate([ { $group: { _id: "$UserInfoID", result: { $sum: 1 } } } ])
從上面(mian)兩段代碼(ma)我們可(ke)以看(kan)到,分組(zu)鍵必(bi)須用(yong)_id,分組(zu)的結果名(ming)稱可(ke)以自(zi)己定義,{$sum:1}每次自(zi)加1。
下面使用(yong)map...reduce也可以實(shi)現分組的功能
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;//定(ding)義一(yi)個變量total , values是(shi)一(yi)個數組 for (var i in values) { total += values[i].count } return { "count": total }; }, finalize: function Finalize(key, reduced) { return reduced; }, out: { inline: 1 } });