摘要:簡(jiǎn)述從字面上來(lái)理解就是兩個(gè)過(guò)程映射以及化簡(jiǎn)。在映射化簡(jiǎn)的過(guò)程都是每臺(tái)服務(wù)器自己的在運(yùn)算,大量的服務(wù)器同時(shí)來(lái)進(jìn)行運(yùn)算工作,這就是大數(shù)據(jù)基本理念。映射操作輸出了鍵值對(duì)結(jié)果。在中,所有的映射化簡(jiǎn)函數(shù)都是使用編寫(xiě),并且運(yùn)行在進(jìn)程中。
簡(jiǎn)述
mapReduce從字面上來(lái)理解就是兩個(gè)過(guò)程:map映射以及reduce化簡(jiǎn)。是一種比較先進(jìn)的大數(shù)據(jù)處理方法,其難度不高,從性能上來(lái)說(shuō)屬于比較暴力的(通過(guò)N臺(tái)服務(wù)器同時(shí)來(lái)計(jì)算),但相較于group以及aggregate來(lái)說(shuō),功能更強(qiáng)大,并更加靈活。
映射過(guò)程:先把某一類(lèi)數(shù)據(jù)分組歸類(lèi),這里的映射過(guò)程是支持分布式的,一邊遍歷每一臺(tái)服務(wù)器,一邊進(jìn)行分類(lèi)。
化簡(jiǎn)過(guò)程:然后再在分組中進(jìn)行運(yùn)算,這里的化簡(jiǎn)過(guò)程也是支持分布式的,在分類(lèi)的過(guò)程中直接運(yùn)算了。也就是說(shuō)如果是一個(gè)求和的過(guò)程,先在a服務(wù)器分組求和,然后再在b服務(wù)器分組求和····最后再把化簡(jiǎn)以后的數(shù)據(jù)進(jìn)行最終處理。在映射化簡(jiǎn)的過(guò)程都是每臺(tái)服務(wù)器自己的CPU在運(yùn)算,大量的服務(wù)器同時(shí)來(lái)進(jìn)行運(yùn)算工作,這就是大數(shù)據(jù)基本理念。
在這個(gè)映射化簡(jiǎn)操作中,MongoDB對(duì)每個(gè)輸入文檔(例如集合中滿足查詢條件的文檔)執(zhí)行了map操作。映射操作輸出了鍵值對(duì)結(jié)果。對(duì)那些有多個(gè)值的關(guān)鍵字,MongoDB執(zhí)reduce操作,收集并壓縮了最終的聚合結(jié)果。然后MongoDB把結(jié)果保存到一個(gè)集合中?;?jiǎn)函數(shù)還可以把結(jié)果輸出到finalize函數(shù),進(jìn)一步對(duì)聚合結(jié)果做處理,當(dāng)然這步是可選的。
在MongoDB中,所有的映射化簡(jiǎn)函數(shù)都是使用JavaScript編寫(xiě),并且運(yùn)行在 mongod 進(jìn)程中。映射化簡(jiǎn)操作使用一個(gè)集合中文檔作為輸入,并且可以在映射階段之前執(zhí)行任意的排序和限定操作。 mapReduce 命令可以把結(jié)果作為一個(gè)文檔來(lái)返回,也可以把結(jié)果寫(xiě)入集合。輸入集合和輸出集合可以是分片的。
語(yǔ)法參數(shù)更多參考: http://docs.mongodb.org/manual/reference/command/mapReduce/
map: function() {emit(this.cat_id,this.goods_number); }, # 函數(shù)內(nèi)部要調(diào)用內(nèi)置的emit函數(shù),cat_id代表根據(jù)cat_id來(lái)進(jìn)行分組,goods_number代表把文檔中的goods_number字段映射到cat_id分組上的數(shù)據(jù),其中this是指向向前的文檔的,這里的第二個(gè)參數(shù)可以是一個(gè)對(duì)象,如果是一個(gè)對(duì)象的話,也是作為數(shù)組的元素壓進(jìn)數(shù)組里面; reduce: function(cat_id,all_goods_number) {return Array.sum(all_goods_number)}, # cat_id代表著cat_id當(dāng)前的這一組,all_goods_number代表當(dāng)前這一組的goods_number集合,這部分返回的就是結(jié)果中的value值; out:實(shí)例 簡(jiǎn)單應(yīng)用實(shí)例
# 求每組的庫(kù)存總量 var map = function(){ emit(this.cat_id,this.goods_number); } var reduce = function(cat_id,numbers){ return Array.sum(numbers); } db.goods.mapReduce(map,reduce,{out:"res"}) # 查看Array支持的方法 for(var i in Array){ printjson(i); } "contains" "unique" "shuffle" "tojson" "fetchRefs" "sum" "avg" "stdDev" # 求每個(gè)欄目的平均價(jià)格 var map = function(){ emit(this.cat_id,this.shop_price); } var reduce = function(cat_id,prices){ var avgprice = Array.avg(prices); return Math.round(avgprice,2); } db.goods.mapReduce(map,reduce,{out:"res"}); # 求出每組的最大價(jià)格 var map = function(){ emit(this.cat_id,this.shop_price); } //錯(cuò)誤操作 ↓↓ 應(yīng)該在finalize函數(shù)中做處理 var reduce = function(cat_id,prices){ var max = 0; for(var i in prices){ if(i > max) max = i; } return max; } var reduce = function(cat_id,prices){ return {cat_id:cat_id,prices:prices}; } var finalize = function(cat_id, prices) { var max = 0; if(prices.prices !== null){ var obj = prices.prices; for(var i in obj){ if(obj[i] > max) max = obj[i] } } return max == 0 ? prices : max; } db.goods.mapReduce(map,reduce,{out:"res1",finalize:finalize,query:{"shop_price":{$gt:0}}}); # 獲得每組的商品集合 var map = function(){ emit(this.cat_id,this.goods_name); } var reduce = function(cat_id,goods_names){ return {cat_id:cat_id,goods_names:goods_names} } var finalize = function(key, reducedValue) { return reducedValue == null ? "none value" : reducedValue; //對(duì)reduce的值進(jìn)行二次處理 } db.runCommand({ mapReduce:"goods", map:map, reduce:reduce, finalize:finalize, out:"res2" }) # 對(duì)于price大于100的才進(jìn)行分組映射 ## 方法1: var map = function(){ if(this.shop_price > 100){ emit(this.cat_id,{name:this.goods_name,price:this.shop_price}); } } var reduce = function(cat_id,goods_names){ return {cat_id:cat_id,goods_names:goods_names} } db.runCommand({ mapReduce:"goods", map:map, reduce:reduce, out:"res2" }) ## 方法2 首推此方法 var map = function(){ emit(this.cat_id,{name:this.goods_name,price:this.shop_price}); } var reduce = function(cat_id,goods_names){ return {cat_id:cat_id,goods_names:goods_names} } db.runCommand({ mapReduce:"goods", map:map, reduce:reduce, query:{"shop_price":{$gt:100}}, out:"res2" })官網(wǎng)實(shí)例
# 數(shù)據(jù)結(jié)構(gòu) { _id: ObjectId("50a8240b927d5d8b5891743c"), cust_id: "abc123", ord_date: new Date("Oct 04, 2012"), status: "A", price: 25, items: [ { sku: "mmm", qty: 5, price: 2.5 }, { sku: "nnn", qty: 5, price: 2.5 } ] } # 計(jì)算每個(gè)顧客的總金額 var mapFunction1 = function() { emit(this.cust_id, this.price); }; var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); }; db.orders.mapReduce( mapFunction1, reduceFunction1, { out: "map_reduce_example" } ) # 計(jì)算訂單總量和每種 sku 訂購(gòu)量的平均值 var mapFunction2 = function() { for (var idx = 0; idx < this.items.length; idx++) { var key = this.items[idx].sku; var value = { count: 1, qty: this.items[idx].qty }; emit(key, value); } }; var reduceFunction2 = function(keySKU, countObjVals) { reducedVal = { count: 0, qty: 0 }; for (var idx = 0; idx < countObjVals.length; idx++) { reducedVal.count += countObjVals[idx].count; reducedVal.qty += countObjVals[idx].qty; } return reducedVal; }; var finalizeFunction2 = function (key, reducedVal) { reducedVal.avg = reducedVal.qty/reducedVal.count; return reducedVal; }; db.orders.mapReduce( mapFunction2, reduceFunction2, { out: { merge: "map_reduce_example" }, query: { ord_date: { $gt: new Date("01/01/2012") } }, finalize: finalizeFunction2 } )
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/18831.html
摘要:操作花費(fèi)的時(shí)間,單位是毫秒。處理完成后,會(huì)自動(dòng)將臨時(shí)集合的名字更改為你指定的集合名,這個(gè)重命名的過(guò)程是原子性的。作用域在這些函數(shù)內(nèi)部是不變的。上一篇文章指南聚合下一篇文章指南聚合命令 上一篇文章:MongoDB指南---16、聚合下一篇文章:MongoDB指南---18、聚合命令 MapReduce是聚合工具中的明星,它非常強(qiáng)大、非常靈活。有些問(wèn)題過(guò)于復(fù)雜,無(wú)法使用聚合框架的查詢語(yǔ)言...
摘要:操作花費(fèi)的時(shí)間,單位是毫秒。處理完成后,會(huì)自動(dòng)將臨時(shí)集合的名字更改為你指定的集合名,這個(gè)重命名的過(guò)程是原子性的。作用域在這些函數(shù)內(nèi)部是不變的。上一篇文章指南聚合下一篇文章指南聚合命令 上一篇文章:MongoDB指南---16、聚合下一篇文章:MongoDB指南---18、聚合命令 MapReduce是聚合工具中的明星,它非常強(qiáng)大、非常靈活。有些問(wèn)題過(guò)于復(fù)雜,無(wú)法使用聚合框架的查詢語(yǔ)言...
摘要:語(yǔ)法按什么字段進(jìn)行分組進(jìn)行分組前變量初始化該處聲明的變量可以在以下回調(diào)函數(shù)中作為的屬性使用類(lèi)似中的分組后的查詢返回先迭代出分組然后再迭代分組中的文檔即變量就代表當(dāng)前分組中此刻迭代到的文檔變量就代表當(dāng)前分組。 group 語(yǔ)法 db.collection.group({ key:{field:1},//按什么字段進(jìn)行分組 initial:{count:0},//...
摘要:定位于由廉價(jià)服務(wù)器構(gòu)成的超大集群,假定單個(gè)服務(wù)器存儲(chǔ)是不可靠地,易失的,因此強(qiáng)調(diào)冗余和備份。并行計(jì)算的核心技術(shù)框架。一個(gè)典型案例編寫(xiě)一個(gè)應(yīng)用對(duì)圖書(shū)館過(guò)去年的文獻(xiàn),統(tǒng)計(jì)較大詞頻。相同屬性的列組成列族。 - GFS: 分布式文件系統(tǒng)。適用于TB級(jí)超大文件存儲(chǔ)。master節(jié)點(diǎn)是文件管理的大腦,負(fù)責(zé)存儲(chǔ)和管理文件與物理塊的映射,維護(hù)metafile,處理臨時(shí)文件,調(diào)度chunk server等...
閱讀 2436·2019-08-29 13:53
閱讀 2517·2019-08-29 11:32
閱讀 3057·2019-08-28 17:51
閱讀 3803·2019-08-26 10:45
閱讀 3523·2019-08-23 17:51
閱讀 2992·2019-08-23 16:56
閱讀 3345·2019-08-23 16:25
閱讀 3099·2019-08-23 14:15