map

英[m?p] 美[m?p]

n. ??, ?? ??; ??, ??? ??

vt . ?? ???(?? ?), ?? ??; ; ?????

vi. ????; (??) ?????

MongoDB ? ?? ?? ???

??: Map-Reduce? ??? ??? ??? ?? ??? ??(???)? ??? ??(MAP) ??? ?? ??(REDUCE)? ???? ??? ?????. MongoDB?? ???? Map-Reduce? ?? ???? ??? ??? ??? ?? ??????.

??: ??>db.collection.mapReduce( function() {emit(key,value);}, //map function
function(key,values) {return ??Function}, //?? ?? {out: collection, query: document, sort: document,limit: number }) MapReduce? ???? Map ??? Reduce ???? ? ?? ??? ?????. Map ??? Emit(key, value)? ???? ???? ?? ???? ????, ??? ?? ?? ?? Reduce ??? ?????. Map ??? ?-? ?? ???? ?? Emit(key, value)? ???? ???.

????: map: ?? ??(?? ?? ????? ??? ?-? ?? ?????). ?? ?? ???? ?? ??? ??? ?-?? ?-??? ???? ?, ? ? ??? ?? ? ??? ???? ????. . out ?? ??? ???? ?????(???? ??? ?? ???? ???? ????? ??? ?? ? ???? ?????). ??? ??? ?????. ??? ???? ??? ?? ??? ?????. (??, ?? ? ??? ???? ?? ??) ?? ? ??(??? ? ???? ??? ?? ?? ??)? ??? ?? ?? ????? ??? ???? ??? ????? ??? ??? ??? ? ????. ?? ???? ??? ??? ??(??? ??? ?????? ?? ??? ????)

MongoDB ? ?? ?? ?

>db.posts.insert({
   "post_text": "php中文網(wǎng),最全的技術(shù)文檔。",
   "user_name": "mark",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "php中文網(wǎng),最全的技術(shù)文檔。",
   "user_name": "mark",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "php中文網(wǎng),最全的技術(shù)文檔。",
   "user_name": "mark",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "php中文網(wǎng),最全的技術(shù)文檔。",
   "user_name": "mark",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "php中文網(wǎng),最全的技術(shù)文檔。",
   "user_name": "mark",
   "status":"disabled"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "php中文網(wǎng),最全的技術(shù)文檔。",
   "user_name": "php",
   "status":"disabled"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "php中文網(wǎng),最全的技術(shù)文檔。",
   "user_name": "php",
   "status":"disabled"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "php中文網(wǎng),最全的技術(shù)文檔。",
   "user_name": "php",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })
現(xiàn)在,我們將在 posts 集合中使用 mapReduce 函數(shù)來選取已發(fā)布的文章(status:"active"),并通過user_name分組,計算每個用戶的文章數(shù):

>db.posts.mapReduce( 
   function() { emit(this.user_name,1); }, 
   function(key, values) {return Array.sum(values)}, 
      {  
         query:{status:"active"},  
         out:"post_total" 
      }
)
以上 mapReduce 輸出結(jié)果為:

{
        "result" : "post_total",
        "timeMillis" : 23,
        "counts" : {
                "input" : 5,
                "emit" : 5,
                "reduce" : 1,
                "output" : 2
        },
        "ok" : 1
}
結(jié)果表明,共有4個符合查詢條件(status:"active")的文檔, 在map函數(shù)中生成了4個鍵值對文檔,最后使用reduce函數(shù)將相同的鍵值分為兩組。



具體參數(shù)說明:

result:儲存結(jié)果的collection的名字,這是個臨時集合,MapReduce的連接關(guān)閉后自動就被刪除了。

timeMillis:執(zhí)行花費的時間,毫秒為單位

input:滿足條件被發(fā)送到map函數(shù)的文檔個數(shù)

emit:在map函數(shù)中emit被調(diào)用的次數(shù),也就是所有集合中的數(shù)據(jù)總量

ouput:結(jié)果集合中的文檔個數(shù)(count對調(diào)試非常有幫助)

ok:是否成功,成功為1

err:如果失敗,這里可以有失敗原因,不過從經(jīng)驗上來看,原因比較模糊,作用不大

使用 find 操作符來查看 mapReduce 的查詢結(jié)果:

>db.posts.mapReduce( 
   function() { emit(this.user_name,1); }, 
   function(key, values) {return Array.sum(values)}, 
      {  
         query:{status:"active"},  
         out:"post_total" 
      }
).find()
以上查詢顯示如下結(jié)果,兩個用戶 tom 和 mark 有兩個發(fā)布的文章:

{ "_id" : "mark", "value" : 4 }
{ "_id" : "php", "value" : 1 }
用類似的方式,MapReduce可以被用來構(gòu)建大型復(fù)雜的聚合查詢。

Map函數(shù)和Reduce函數(shù)可以使用 JavaScript 來實現(xiàn),使得MapReduce的使用非常靈活和強大。