2016-04-22 54 views
-1

我在Mongo DB集合中有400,000個數據。每個Document都有count(number)。我想讀取這些文檔並添加所有數字以獲得total.I使用Node獲取Mongo DB Collection數據.js和貓鼬,然後計算使用for-loop.it總共需要兩分鐘左右,我想在一秒鐘內完成。有沒有什麼辦法可以加速這個過程?我發現mapreduce可以加速這個。什麼是最有效的方法加快這一進程。如何加快MongoDB中的數據讀取速度

我把MongoDB的模型這樣

exports.getDownloads = function(processPD,processDW,responseMDW) { 
    DailyDowloadsModel.find({},function(err,foundData){ 
     var select; 
     if (err) { 
      log.error(clientIP +" - DB Connection downloads failed - error"); 
      res.status(500).send(); 
     } 
     else { 
      if(foundData.length == 0){ 
       var responseObject = null; 
       if(select && select == 'count'){ 
        responseObject = {count: 0}; 
       } 
      }else { 
       var responseObject = foundData; 
       if (select && select == "count") { 
        responseObject = {count: foundData.length}; 
       } 
       processPD(processDW,responseObject,responseMDW); 
      } 
     } 
    }); 
} 

樣本文件

{ 
    "_id" : ObjectId("5719ef37264f87331a3d0c54"), 
    "refunds" : "0", 
    "downloads" : "6", 
    "country" : "CA", 
    "date" : "2013-09-06", 
    "product_id" : "20600001319328", 
    "__v" : 0 
} 

我要計算總的下載。

+0

您的平均文檔有多大?請發佈示例文檔。 – Saleem

+0

我添加一個示例文件 – heshjse

+0

好。計數(數字)在哪裏?正如你在上面的陳述中提到的那樣。 – Saleem

回答

2

您有兩種選擇來計算總數。

選項1:聚合框架

執行使用聚合框架這樣的動作會快很多比發送所有文件交給客戶和做數學在那邊。

注意:您的downloads字段是字符串,它應該是一個數字。

db.collection.aggregate([ 
{$group:{_id:null, total:{$sum:"$downloads"}}} 
]) 

在我的機器(Macbook Pro)上,它在不到半秒的時間內返回總計。我正在對400000個文檔進行測試。

選項2:地圖降低 雖然強烈推薦更新您的文檔結構接受downloads的數量。但是,如果出於任何原因這不是一個選項,最好的選擇是MongoDB提供的地圖縮減功能。

var map = function(){ 
    emit(1, parseInt(this.downloads)); 
}; 

var reduce = function(key, values){ 
    var reducedValue = Array.sum(values); 
    return reducedValue; 
}; 

db.collection.mapReduce(map, reduce, { 
    out: { "inline" : 1} 
}); 

如你所見,map reduce比聚合框架慢,但比你的原始方法快得多。它發出輸出:

{ 
    "results" : [ 
     { 
      "_id" : NumberInt(1), 
      "value" : NumberInt(2400000) 
     } 
    ], 
    "timeMillis" : NumberInt(4112), 
    "counts" : { 
     "input" : NumberInt(400000), 
     "emit" : NumberInt(400000), 
     "reduce" : NumberInt(4000), 
     "output" : NumberInt(1) 
    }, 
    "ok" : NumberInt(1) 
} 

正如你可以看到,它大概用了4秒即可完成操作。