中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MongoDB:MapReduce基礎及實例

發布時間:2020-06-05 20:49:03 來源:網絡 閱讀:897 作者:joe321 欄目:MongoDB數據庫

背景

     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的東西.

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

枣庄市| 寻乌县| 怀化市| 区。| 通化县| 车致| 宜章县| 邛崃市| 阜南县| 长海县| 林甸县| 阜新| 朝阳县| 巴中市| 莱芜市| 蒙自县| 永修县| 佛冈县| 香河县| 丹巴县| 义乌市| 宁陵县| 南开区| 蒙阴县| 读书| 德令哈市| 亳州市| 金秀| 桦川县| 朝阳市| 洪洞县| 张家港市| 法库县| 洮南市| 桑日县| 阳春市| 咸阳市| 贵港市| 高陵县| 莎车县| 贵溪市|