MongoDB聚合操作3——MapReduce

本篇主要講解 MapReduce 編程模型。MapReduce是一種計算模型啡专,簡單的說就是將大批量的工作(數(shù)據(jù))分解(MAP)執(zhí)行裆赵,然后再將結(jié)果合并成最終結(jié)果(REDUCE)采记。

一劣坊、MapReduce 命令

MapReduce 的基本語法如下:

>db.collection.mapReduce(
   function() {emit(key,value);},  //map 函數(shù)
   function(key,values) {return reduceFunction},   //reduce 函數(shù)
   {
      out: collection,
      query: document,
      sort: document,
      limit: number,
      finalize: <function>,
      scope: <document>,
      jsMode: <boolean>,
      verbose: <boolean>
   }
)

使用 MapReduce 要實現(xiàn)兩個函數(shù) Map 函數(shù)和 Reduce 函數(shù),Map 函數(shù)調(diào)用 emit(key, value), 遍歷 collection 中所有的記錄, 將 key 與 value 傳遞給 Reduce 函數(shù)進(jìn)行處理螃概。
參數(shù)說明:

  • map:是JavaScript 函數(shù)矫夯,負(fù)責(zé)將每一個輸入文檔轉(zhuǎn)換為零或多個文檔,通過key進(jìn)行分組吊洼,生成鍵值對序列,作為 reduce 函數(shù)參數(shù)
  • reduce:是JavaScript 函數(shù)训貌,對map操作的輸出做合并的化簡的操作(將key-values變成key-value,也就是把values數(shù)組變成一個單一的值value)
  • out:統(tǒng)計結(jié)果存放集合 (不指定則使用臨時集合,在客戶端斷開后自動刪除)冒窍。
  • query: 一個篩選條件递沪,只有滿足條件的文檔才會調(diào)用map函數(shù)。(query综液。limit款慨,sort可以隨意組合)
  • sort: 和limit結(jié)合的sort排序參數(shù)(也是在發(fā)往map函數(shù)前給文檔排序),可以優(yōu)化分組機(jī)制
  • limit: 發(fā)往map函數(shù)的文檔數(shù)量的上限(要是沒有l(wèi)imit谬莹,單獨使用sort的用處不大)
  • finalize:可以對reduce輸出結(jié)果再一次修改檩奠,跟group的finalize一樣,不過MapReduce沒有g(shù)roup的4MB文檔的輸出限制
  • scope:向map附帽、reduce埠戳、finalize導(dǎo)入外部變量
  • verbose:是否包括結(jié)果信息中的時間信息,默認(rèn)為fasle

關(guān)于MapReduce的工作流程如下:

image

在集合 orders 中查找 status:"A" 的數(shù)據(jù)蕉扮,并根據(jù) cust_id 來分組整胃,并計算 amount 的總和。

二喳钟、使用示例

對以下結(jié)構(gòu)的文檔進(jìn)行統(tǒng)計屁使。統(tǒng)計每個用戶的文章數(shù)量。

>db.col.find()
{
    "_id" : ObjectId("5c09dfcde354b306e46af7f3"),
    "bookname" : "Java 8 實戰(zhàn)",
    "author" : "simon",
    "status" : "active"
},
{
    "_id" : ObjectId("5c09dfdee354b306e46af7f4"),
    "bookname" : "MongoDB權(quán)威指南",
    "author" : "simon",
    "status" : "active"
},
{
    "_id" : ObjectId("5c09dfffe354b306e46af7f5"),
    "bookname" : "MyBatis 實戰(zhàn)",
    "author" : "simon",
    "status" : "disabled"
},
{
    "_id" : ObjectId("5c09e016e354b306e46af7f6"),
    "bookname" : "MyBatis 從入門到具精通",
    "author" : "Aaron",
    "status" : "disabled"
},
{
    "_id" : ObjectId("5c09e02ce354b306e46af7f7"),
    "bookname" : "Spring Boot 2.0",
    "author" : "Aaron",
    "status" : "active"
},
{
    "_id" : ObjectId("5c09e037e354b306e46af7f8"),
    "bookname" : "Spring Cloud",
    "author" : "Aaron",
    "status" : "active"
},
{
    "_id" : ObjectId("5c09e038e354b306e46af7f9"),
    "bookname" : "Spring Cloud",
    "author" : "Aaron",
    "status" : "active"
}

將在 col 集合中使用 mapReduce 函數(shù)來選取已發(fā)布的文章(status:"active")奔则,并通過author分組屋灌,計算每個用戶的文章數(shù)

>db.col.mapReduce(
   function() { emit(this.author,1); },
   function(key, values) {return Array.sum(values)},
      {  
         query:{status:"active"},  
         out:"total"
      }
)
{
    "result" : "total",
    "timeMillis" : 422.0,
    "counts" : {
        "input" : 5,
        "emit" : 5,
        "reduce" : 2,
        "output" : 2
    },
    "ok" : 1.0,
    "_o" : {
        "result" : "total",
        "timeMillis" : 422,
        "counts" : {
            "input" : 5,
            "emit" : 5,
            "reduce" : 2,
            "output" : 2
        },
        "ok" : 1.0
    },
    "_keys" : [
        "result",
        "timeMillis",
        "counts",
        "ok"
    ],
    "_db" : {
        "_mongo" : {
            "slaveOk" : true,
            "host" : "192.168.10.58:27017",
            "defaultDB" : "test",
            "_readMode" : "commands",
            "_writeMode" : "commands"
        },
        "_name" : "ibase_dev"
    },
    "_coll" : {
        "_mongo" : {
            "slaveOk" : true,
            "host" : "192.168.10.58:27017",
            "defaultDB" : "test",
            "_readMode" : "commands",
            "_writeMode" : "commands"
        },
        "_db" : {
            "_mongo" : {
                "slaveOk" : true,
                "host" : "192.168.10.58:27017",
                "defaultDB" : "test",
                "_readMode" : "commands",
                "_writeMode" : "commands"
            },
            "_name" : "ibase_dev"
        },
        "_shortName" : "total",
        "_fullName" : "ibase_dev.total"
    }
}

從結(jié)果中可以看出,一共有5個文檔服務(wù){status:'active'}的文檔应狱,在map函數(shù)中生成了5個鍵值對文檔,最后使用reduce函數(shù)將相同的鍵值分為 2 組祠丝。

具體參數(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)試非常有幫助),out: { inline: 1 }不會創(chuàng)建集合,結(jié)果在內(nèi)存中
  • ok:是否成功叠蝇,成功為1
  • err:如果失敗璃岳,這里可以有失敗原因,不過從經(jīng)驗上來看,原因比較模糊铃慷,作用不大

查看執(zhí)行結(jié)果:

>db.total.find()
{
    "_id" : "Aaron",
    "value" : 3.0
},
{
    "_id" : "simon",
    "value" : 2.0
}

鏈接:http://www.reibang.com/p/fd94a52881ee
來源:簡書

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末单芜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子犁柜,更是在濱河造成了極大的恐慌洲鸠,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件馋缅,死亡現(xiàn)場離奇詭異扒腕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)萤悴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進(jìn)店門瘾腰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人覆履,你說我怎么就攤上這事蹋盆。” “怎么了内狗?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵怪嫌,是天一觀的道長。 經(jīng)常有香客問我柳沙,道長岩灭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任赂鲤,我火速辦了婚禮噪径,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘数初。我一直安慰自己找爱,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布泡孩。 她就那樣靜靜地躺著车摄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仑鸥。 梳的紋絲不亂的頭發(fā)上吮播,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天,我揣著相機(jī)與錄音眼俊,去河邊找鬼意狠。 笑死,一個胖子當(dāng)著我的面吹牛疮胖,可吹牛的內(nèi)容都是我干的环戈。 我是一名探鬼主播闷板,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼院塞!你這毒婦竟也來了遮晚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤迫悠,失蹤者是張志新(化名)和其女友劉穎鹏漆,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體创泄,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡艺玲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鞠抑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饭聚。...
    茶點故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖搁拙,靈堂內(nèi)的尸體忽然破棺而出秒梳,到底是詐尸還是另有隱情,我是刑警寧澤箕速,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布酪碘,位于F島的核電站,受9級特大地震影響盐茎,放射性物質(zhì)發(fā)生泄漏兴垦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一字柠、第九天 我趴在偏房一處隱蔽的房頂上張望探越。 院中可真熱鬧,春花似錦窑业、人聲如沸钦幔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鲤氢。三九已至,卻和暖如春西潘,著一層夾襖步出監(jiān)牢的瞬間铜异,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工秸架, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咆蒿。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓东抹,卻偏偏與公主長得像蚂子,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缭黔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,566評論 2 349