2013-05-08 23 views
1

我正在運行地圖縮減操作並以壞數據結束。這裏是我的地圖和減少功能:使用嵌套對象縮小MongoDB地圖

var map_analytics = function() { 
    var key = this.owner; 
    if (this.apikey == null) { 
     var value = {api_call_with_key: 0, api_call_without_key: 1}; 
    } else { 
     var value = {api_call_with_key: 1, api_call_without_key: 0}; 
    } 
    emit(key, value); 
}; 

var reduce_analytics = function(key_owner, api_calls) { 
    today = new Date(); 
    firstofmonth = new Date(today.getFullYear(), today.getMonth(), 1); 
    reduced_val = {period: firstofmonth, analytics: {api_call_with_key: 0, api_call_without_key: 0}}; 
    api_calls.forEach(function(value) { 
     reduced_val.analytics.api_call_with_key += value.api_call_with_key; 
     reduced_val.analytics.api_call_without_key += value.api_call_without_key; 
    }); 
    return reduced_val; 
}; 

現在,當我跑我的地圖減少:

db.statistics.mapReduce(map_analytics, reduce_analytics, {out: { reduce: "analytics" }, query: { request_date: { $gte: firstofmonth}}}) 

我得到這個:

{ 
     "_id" : ObjectId("5136d880136b961c98c9a62f"), 
     "value" : { 
       "period" : ISODate("2013-05-01T06:00:00Z"), 
       "analytics" : { 
         "api_call_with_key" : NaN, 
         "api_call_without_key" : NaN 
       } 
     } 
} 

任何想法,爲什麼我得到的NaN而不是實際值?

這更簡單的版本的作品:

var reduce_analytics = function(key_owner, api_calls) { 
    reduced_val = {api_call_with_key: 0, api_call_without_key: 0}; 
    api_calls.forEach(function(value) { 
     reduced_val.api_call_with_key += value.api_call_with_key; 
     reduced_val.api_call_without_key += value.api_call_without_key; 
    }); 
    return reduced_val; 
}; 

,併產生

{ 
     "_id" : ObjectId("5143b2c8136b9616343dacec"), 
     "value" : { 
       "api_call_with_key" : 0, 
       "api_call_without_key" : 2, 
       "total_api_calls" : 2 
     } 
} 

我怎麼能輸出更復雜的對象?

回答

1

您無法更改map和reduce之間的值的格式。

換句話說,當你的地圖發出(key,VALUE)時,你的reduce函數必須返回相同的格式VALUE。

所以如果你想把日期作爲你的價值的一部分,你需要在映射階段把它放進去。如果按鍵,日期分組,則它應該是關鍵文檔的一部分。

此外,如果可以的話,我會建議使用聚合框架 - 它比map-reduce要快得多。

+0

並牢記減少函數可以被稱爲零,一次或一次以上每個鍵值。 – 2013-05-08 04:42:31

+0

我剛剛在這裏發現了這個:http://stackoverflow.com/a/7340000/1563654。這是正確的答案。謝謝。 – 2013-05-08 05:21:53

0

試試這個:

api_calls.forEach(function(value) { 
    reduced_val.analytics.api_call_with_key += Number(value.api_call_with_key); 
    reduced_val.analytics.api_call_without_key += Number(value.api_call_without_key); 
});