MongoDB GroupBy操做, 結果集大小限制問題。

出現問題      

  公司是作互聯網廣告投放的,須要統計廣告展示量在前五百的域名。最簡單粗暴的作法就是group by,根據url分組,而後再sort一下就搞定曬!結果問題就出現了。java

以下統計的2015-02-28當日22時的日誌,文檔數量:904405。web

db['log.2015-02-28_22'].group({
     key : {domainUrl:1}, 
     initial : {count:0}, 
     reduce : function Reduce(doc, out) {
	out.count++;
}

    報錯:mongodb

Error in executing GroupBy
Command 'group' failed: exception: group() can't handle more than 20000 unique keys (response: { "errmsg" : "exception: group() can't handle more than 20000 unique keys", "code" : 17203, "ok" : 0.0 })
Type: MongoDB.Driver.MongoCommandException

    錯誤信息不夠具體,加之理解問題,我覺得是集合中的文檔數量不能超過20000,2萬都不能支持那要group幹嗎。通過屢次測試,終於證實了我是錯的。是不支持大於2萬的結果集,即分組後產生的文檔數量不能超過2萬。app

//集合大小
> db['log.2015-02-28_22'].count();
904405
//惟一url數量
> db['log.2015-02-28_22'].distinct('domainUrl').length;
20738

這個集合中的惟一url數量是20738,恰好超過了2萬,因此MongoDB的group就無能爲力了。dom

另外測試還意外發現,distinct對結果集大小也是有限制的。結果集大小不能超過16Mb。函數

> db['log.2015-02-28_22'].distinct('webUrl').length;
     distinct failed: {
        "errmsg" : "exception: distinct too big, 16mb cap",
        "code" : 17217,
        "ok" : 0

MongoDB爲何這麼多限制,並且閾值都比較小,還請大神指點。學習

解決問題

    問題是用來解決的,經過stackoverflow大神的指點,我嘗試着用MongoDB的mapreduce搞定它,其實一開始我是拒絕的,由於,你不能讓我用,我就用;首先,我要看一下我會不會用。結果發現,我不會用,而後看了看MongoDB的說明文檔。寫出以下代碼:測試

db.runCommand({ mapreduce: "log.2015-02-28_22", 
 map : function Map() {
	emit(
		{   uuid:this.adUUId, //對不一樣的廣告統計url
                    url:this.domainUrl
                },
		{count: 1}	
	); 
 },
 reduce : function Reduce(key, values) {
    var total=0;
	for( var i in values){ 
 		total +=values[i].count;
	} 
 
	return {count:total};	
},
 finalize : function Finalize(key, reduced) {
	return reduced;
},
 out : { inline : 1 }
});

我用了一次,感受效果還不錯。如今也推薦給你試一下。ui

結果對象的結構以下:this

{ "_id" : { "uuid" : "inmobi" , "url" : "static.51y5.net" } , "value" : { "count" : 82409.0}}
{ "_id" : { "uuid" : "inmobi" , "url" : "applet.kakamobi.com"} , "value" : { "count" : .23714.0}}

_id屬性中是分組字段,value屬性中保存結果對象。mongodb聚合函數產生的count是double類型的。你能夠在finalize方法中處理一下,轉換成整型。我是在java 代碼轉換的。

MongoDB的Mapreduce我也是第一次用,更具體的用法詳解,待我研究以後,再作報告。由於我不肯意寫完之後,再加點特技上去,文章「duang」一下,很贊,很勁,這樣讀者出來必定會罵我,博主根本就是不會,還裝逼。(just kidding.)

以上內容有不對的地方,還望你們指正,虛心學習。

Thanks a lot ,END!

相關文章
相關標籤/搜索