Mongodb MapReduce使用

百聯達發表於2016-05-26
一: 背景

在利用mongodb的Group進行資料分析的時候,發現是有限制的,非唯一索引記錄數不能大於20000,進而考慮使用MapReduce.

二:MapReduce的命令語法
db.runCommand(
 { mapreduce : 字串,集合名,
   map : 函式,見下文
   reduce : 函式,見下文
   [, query : 文件,發往map函式前先給過渡文件]
   [, sort : 文件,發往map函式前先給文件排序]
   [, limit : 整數,發往map函式的文件數量上限]
   [, out : 字串,統計結果儲存的集合]
   [, keeptemp: 布林值,連結關閉時臨時結果集合是否儲存]
   [, finalize : 函式,將reduce的結果送給這個函式,做最後的處理]
   [, scope : 文件,js程式碼中要用到的變數]
   [, jsMode : 布林值,是否減少執行過程中BSON和JS的轉換,預設true] //注:false時 BSON-->JS-->map-->BSON-->JS-->reduce-->BSON,可處理非常大的mapreduce,<br>                                    //true時BSON-->js-->map-->reduce-->BSON
   [, verbose : 布林值,是否產生更加詳細的伺服器日誌,預設true]
 }
);

三:Spring mongodb MapReduce程式碼例項

例項用來統計某個使用者在一定時間端內訪問某個系統某個介面的次數,已經花費的總時間。

請參見程式碼:


點選(此處)摺疊或開啟

  1. Log.info("=================gmap 日誌收集開始===================================");
  2.         try {
  3.             Date date = new Date();
  4.             Date fromDate = GbdDateUtils.getBeginDate(date);
  5.             Date endDate = GbdDateUtils.getEndDate(date);
  6.             Criteria criteria = Criteria.where("date").gte(fromDate).lt(endDate);
  7.             Query query=new Query(criteria);
  8.            
  9.             String mapFunction = "function Map() {emit({\"userId\":this.userId,\"system\":this.system,\"url\":this.url},{count: 1, time: this.time});}";
  10.             String reduceFunction = "function Reduce(key, values) {var reduced = {count:0, time:0};values.forEach(function(val) {reduced.count += val.count;reduced.time += val.time;});return reduced;}";
  11.             MapReduceResults<LogValueObject> mapReduce = mongoTemplate.mapReduce(query, "logs", mapFunction, reduceFunction,new MapReduceOptions().outputCollection("results"), LogValueObject.class);
  12.    
  13.             logger.info(mapReduce.getCounts());
  14.             //清除已有的日誌記錄
  15.             gmapSystemLogBo.removeCurDateLogs(fromDate);
  16.             
  17.            
  18.             List<GmapSystemLog> systemLogs = new ArrayList<>();
  19.             
  20.             int i=0;
  21.             for(LogValueObject log:mapReduce)
  22.             {
  23.                 
  24.                 GmapSystemLog systemLog = new GmapSystemLog();
  25.                 systemLog.setUserId(log.get_id().getUserId().intValue());
  26.                 systemLog.setUrl(log.get_id().getUrl());
  27.                 systemLog.setSystem(log.get_id().getSystem());
  28.                 systemLog.setCount(log.getValue().getCount().intValue());
  29.                 systemLog.setTime(log.getValue().getTime().intValue());
  30.                 systemLog.setDate(fromDate);
  31.                 systemLog.setCreateDate(date);
  32.                 systemLogs.add(systemLog);
  33.                 i++;
  34.                 if (0 < i && (i % 1000 == 0)) {
  35.                     logger.info("==========儲存到資料庫===============");
  36.                     gmapSystemLogBo.batchInsertLogs(systemLogs);
  37.                     systemLogs.clear();
  38.                 }
  39.             }
  40.             
  41.         
  42.             if (0 < systemLogs.size()) {
  43.                 logger.info("==========儲存到資料庫(結束頁)===============");
  44.                 gmapSystemLogBo.batchInsertLogs(systemLogs);
  45.             }
  46.             Log.info("=================gmap 日誌收集結束===================================");

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28624388/viewspace-2107068/,如需轉載,請註明出處,否則將追究法律責任。

相關文章