在使用mongoDB 中Group時,分組欄位不是唯一索引記錄數不能大於2000

來源:互聯網
上載者:User

我在一次統計中,用mongoDB中的Group 對一張記錄數100W表進行匯總。

結果出現異常資訊。

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" : 10043, "ok" : 0.0 })
Type: MongoDB.Driver.MongoCommandException


從異常資訊可以看出mongoDB中的group是有限制的,非唯一索引記錄數不能大於20000,。

不過我沒有研究,怎麼去設定mongoDB參數,來取消這個限制。

但是可以用mongoDB中mapReduce,依然可以完成統計需求。

mapReduce初級使用可以參考:http://www.kafka0102.com/2010/09/329.html


這裡還是簡單說一下自己理解mongDB MapReduce原理。

Map 就是映射,Reduce化簡。

意思就是在統計的時候我需要先根據你定義的規則來收集資訊(執行Map操作),

然後再從你收集的資訊裡面提取你想要資料(reduce)。

先卡看一下文法:

文法介紹

MapReduce是mongodb中的一個Command,它的文法格式如下:

db.runCommand( { mapreduce : <collection>,   map : <mapfunction>,   reduce : <reducefunction>   [, query : <query filter object>]   [, sort : <sort the query.  useful for optimization>]   [, limit : <number of objects to return from collection>]   [, out : <output-collection name>]   [, keeptemp: <true|false>]   [, finalize : <finalizefunction>]   [, scope : <object where fields go into javascript global scope >]   [, verbose : true] });



對於該Command,必有的3個參數我就不解釋了。對於選擇性參數,這裡簡要說明如下:
(1) query是很常用的,它用來在map階段過濾查詢條件的以限定MapReduce操作的記錄範圍。
(2) 和query相關的還有sort和limit,我起初以為它倆是用在reduce階段,實際上和query一起用在map階段。
(3) mongodb預設是建立一個臨時的collection儲存MapReduce結果,當用戶端串連關閉或者顯示使用collection.drop(),這個臨時的collection會被刪除掉。這也就說,預設的keeptemp是false,如果keeptemp為true,那麼結果collection就是永久的。當然,產生的collection名稱並不友好,所以可以指定out表明永久儲存的collection的名稱(這時不需要再指定keeptemp)。當指定out時,並不是將執行結果直接儲存到out,而是同樣到臨時collection,之後如果out存在則drop掉,最後rename臨時collection為out。
(4) finalize:當MapReduce完成時應用到所有結果上,通常不怎麼使用。
(5) verbose:提供執行時間的統計資訊。

第一步:在Map函數中通常我們會用到emit函數。

emit(
this.city, // how to group
{count: 1, age: this.age}// associated data point (document)
); 

emit函數有兩個參數。

參數1,表示你需要分組的欄位。

參數2,分組中每條資料中需要的欄位。

在Map執行完成後我們可以想象成,收集的資料存入一個map集合中,group欄位是key,value值是分組中多條資料。

舉個列子:

有一張表:

班級,學生

1,a

1,b

2,c

2,d

那麼map存放的類容。

map1={1:a,1:b},map2={2:c,2:d} (這是value值)

map={1:map1,2:map2};

第二步:然後再執行reduce.

對於map中每一項都會調用一次reduce函數。

具體函數:

function Reduce(key, values) {
/*
var reduced = {count:0, age:0}; // initialize a doc (same format as emitted value)
values.forEach(function(val) {
reduced.age   += val.age; // reduce logic
reduced.count += val.count; 
});
return reduced;
*/
return values[0];
}


第三步:是可選的選項。這裡主要介紹以下finalize

   [, query : <query filter object>]   [, sort : <sort the query.  useful for optimization>]   [, limit : <number of objects to return from collection>]   [, out : <output-collection name>]   [, keeptemp: <true|false>]   [, finalize : <finalizefunction>]   [, scope : <object where fields go into javascript global scope >]   [, verbose : true]



finalize是最終的意思,就是對mapReduce後的資料再一次處理,就相當於在關聯式資料庫中group by以後的having操作。

比如說我們需要過濾count數大於10條記錄的。或者求平均數等待。

function Finalize(key, reduced) {
/*  

// Make final updates or calculations
reduced.avgAge = reduced.age / reduced.count;

*/
if(reduced.count>10){return;} //過濾記錄數大於10
return reduced;
}



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.