MapReduce是個非常靈活和強大的數據聚合工具。它的好處是可以把一個聚合任務分解為多個小的任務,分配到多服務器上并行處理。
成都創新互聯公司是網站建設專家,致力于互聯網品牌建設與網絡營銷,專業領域包括網站設計制作、成都網站制作、電商網站制作開發、微信平臺小程序開發、微信營銷、系統平臺開發,與其他網站設計及系統開發公司不同,我們的整合解決方案結合了恒基網絡品牌建設經驗和互聯網整合營銷的理念,并將策略和執行緊密結合,且不斷評估并優化我們的方案,為客戶提供全方位的互聯網品牌整合方案!MongoDB也提供了MapReduce,當然查詢語肯定是JavaScript。MongoDB中的MapReduce主要有以下幾階段:
1. Map:把一個操作Map到集合中的每一個文檔
2. Shuffle: 根據Key分組對文檔,并且為每個不同的Key生成一系列(>=1個)的值表(List of values)。
3. Reduce: 處理值表中的元素,直到值表中只有一個元素。然后將值表返回到Shuffle過程,循環處理,直到每個Key只對應一個值表,并且此值表中只有一個元素,這就是MR的結果。
4. Finalize:此步驟不是必須的。在得到MR最終結果后,再進行一些數據“修剪”性質的處理。
MongoDB中使用emit函數向MapReduce提供Key/Value對。
Reduce函數接受兩個參數:Key,emits. Key即為emit函數中的Key。 emits是一個數組,它的元素就是emit函數提供的Value。
Reduce函數的返回結果必須要能被Map或者Reduce重復使用,所以返回結果必須與emits中元素結構一致。
Map或者Reduce函數中的this關鍵字,代表當前被Mapping文檔。
測試數據: 這個集合是三個用戶購買的產品和產品價格的數據。
CodeCodefor(var i=0;i<1000;i++){ var rID=Math.floor(Math.random()*10); var priceparseFloat((Math.random()*10).toFixed(2)); if(rID<4){ db.test.insert({"user":"Joe","sku":rID,"price":price}); } else if(rID>=4 && rID<7) { db.test.insert({"user":"Josh","sku":rID,"price":price}); } else { db.test.insert({"user":"Ken","sku":rID,"price":price}); } }
1. 每個用戶各購買了多少個產品?(單一Key做MR)
Code//SQL實現select user,count(sku) from test group by user//MapReduce實現map=function (){ emit(this.user,{count:1}) } reduce=function (key,values){ var cnt=0; values.forEach(function(val){ cnt+=val.count;}); return {"count":cnt}; }//MR結果存到集合mr1db.test.mapReduce(map,reduce,{out:"mr1"})//查看MR之后結果> db.mr1.find() { "_id" : "Joe", "value" : { "count" : 416 } } { "_id" : "Josh", "value" : { "count" : 287 } } { "_id" : "Ken", "value" : { "count" : 297 } }
2. 每個用戶不同的產品購買了多少個?(復合Key做MR)
Code//SQL實現select user,sku,count(*) from test group by user,sku//MapReduce實現map=function (){ emit({user:this.user,sku:this.sku},{count:1}) } reduce=function (key,values){ var cnt=0; values.forEach(function(val){ cnt+=val.count;}); return {"count":cnt}; } db.test.mapReduce(map,reduce,{out:"mr2"}) > db.mr2.find() { "_id" : { "user" : "Joe", "sku" : 0 }, "value" : { "count" : 103 } } { "_id" : { "user" : "Joe", "sku" : 1 }, "value" : { "count" : 106 } } { "_id" : { "user" : "Joe", "sku" : 2 }, "value" : { "count" : 102 } } { "_id" : { "user" : "Joe", "sku" : 3 }, "value" : { "count" : 105 } } { "_id" : { "user" : "Josh", "sku" : 4 }, "value" : { "count" : 87 } } { "_id" : { "user" : "Josh", "sku" : 5 }, "value" : { "count" : 107 } } { "_id" : { "user" : "Josh", "sku" : 6 }, "value" : { "count" : 93 } } { "_id" : { "user" : "Ken", "sku" : 7 }, "value" : { "count" : 98 } } { "_id" : { "user" : "Ken", "sku" : 8 }, "value" : { "count" : 83 } } { "_id" : { "user" : "Ken", "sku" : 9 }, "value" : { "count" : 116 } }
3. 每個用戶購買的產品數量,總金額是多少?(復合Reduce結果處理)
Code//SQL實現select user,count(sku),sum(price) from test group by user//MapReduce實現map=function (){ emit(this.user,{amount:this.price,count:1}) } reduce=function (key,values){ var res={amount:0,count:0} values.forEach(function(val){ res.amount+=val.amount; res.count+=val.count }); return res; } db.test.mapReduce(map,reduce,{out:"mr3"}) > db.mr3.find() { "_id" : "Joe", "value" : { "amount" : 2053.8899999999994, "count" : 395 } } { "_id" : "Josh", "value" : { "amount" : 1409.2600000000002, "count" : 292 } } { "_id" : "Ken", "value" : { "amount" : 1547.7700000000002, "count" : 313 } }
4. 在3中返回的amount的float精度需要改成兩位小數,還需要得到商品的平均價格。(使用Finalize處理reduce結果集)
Code//SQL實現select user,cast(sum(price) as decimal(10, 2)) as amount,count(sku) as [count], cast((sum(price)/count(sku)) as decimal(10,2)) as avgPrice from test group by user//MapReduce實現map=function (){ emit(this.user,{amount:this.price,count:1,avgPrice:0}) } reduce=function (key,values){ var res={amount:0,count:0,avgPrice:0} values.forEach(function(val){ res.amount+=val.amount; res.count+=val.count }); return res; } finalizeFun=function (key,reduceResult){ reduceResult.amount=(reduceResult.amount).toFixed(2); reduceResult.avgPrice=(reduceResult.amount/reduceResult.count).toFixed(2); return reduceResult;} db.test.mapReduce(map,reduce,{out:"mr4",finalize:finalizeFun}) > db.mr4.find() { "_id" : "Joe", "value" : { "amount" : "2053.89", "count" : 395, "avgPrice" : "5.20" } } { "_id" : "Josh", "value" : { "amount" : "1409.26", "count" : 292, "avgPrice" : "4.83" } } { "_id" : "Ken", "value" : { "amount" : "1547.77", "count" : 313, "avgPrice" : "4.94" } }
5. 統計單價大于6的SKU,每個用戶的購買數量.(篩選數據子集做MR)
這個比較簡單了,只需要將1.中調用MR時加上篩選查詢即可,其它不變.
Codedb.test.mapReduce(map,reduce,{query:{price:{"$gt":6}},out:"mr5"})
MongoDB中的MR工具非常強大,文中的例子只是基礎實例.結合Sharding后,多服務器并行做數據集合處理,才能真正顯現其能力.
如果后續有時間,希望能總結和分享更多關于MongoDB,關于SQL Server的東西.
另外有需要云服務器可以了解下創新互聯cdcxhl.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
新聞標題:MongoDB:MapReduce基礎及實例-創新互聯
路徑分享:http://vcdvsql.cn/article12/iihgc.html
成都網站建設公司_創新互聯,為您提供動態網站、關鍵詞優化、網站改版、響應式網站、云服務器、軟件開發
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯