主要介紹mapReduce在MongoDB中的使用,類似于sql的分組和聚合。首先對Map進行分組,然后使用reduce進行統(tǒng)計,最后可選地使用finalize來調(diào)整最終結(jié)果。嗯,
我先介紹一下,我用的版本是mongodb2.4.5,然后我也用MongoVUE(一個非常好的圖形化mongodb管理工具)幫我配合。
1、原始數(shù)據(jù),集合中有三個doc被使用:
它們的數(shù)據(jù)格式是:
可能很多人不關(guān)注mongodb中存儲的數(shù)據(jù)格式,但對我來說,這是非常敏感的。我不喜歡在后臺使用object來保存這些原本清晰的類型。這里我再多提一點。如果您使用控制臺插入數(shù)據(jù),您插入的數(shù)字,
可能保存為Double,但如果要保存為整數(shù),就必須使用NumberInt()和NumberLong()。示例:
運行后,在控制臺上看不到數(shù)據(jù)類型,但使用MongoVUE,我可以看到:
數(shù)據(jù)庫直接保存為double。并使用:
可以保存為int32,使用NumberLong()保存為Int64。
2.讓MapReduce實現(xiàn)多少人找不同名字的統(tǒng)計。首先是map函數(shù),然后是reduce函數(shù)。
1 function Map() {2 emit(3 this.name, 4 {count: 1} 5); 6} Issue (key, value) is a grouped function,
1 function Reduce(key,values) {2 var reduced={count:0,name:' ' };//初始化返回值3價值觀。foreach(function(val){ 4已減少。計數(shù)=val。數(shù)數(shù);5 });6退貨減少;7 }接下來是減少函數(shù),
好了,讓我們看看如何在DB控制臺下調(diào)用這個MapReduce:
1分貝。run命令({ MapReduce:' le kko '2 Map:function Map(){ 3 emit(4 this。姓名,5 { count:1 } 6);7 },8 reduce : function Reduce(key,values) { 9 var reduced={count:0,name:' ' };//初始化返回值10個值。foreach(function(val){ 11已減少。計數(shù)=val。數(shù)數(shù);12 });13返回減少;14 },15 out:{ inline:1 } 16 });結(jié)果很快出來了:
因為我之前在控制臺下又添加了兩個文檔,所以現(xiàn)在有四個人叫l(wèi)ekko。值得注意的是,這里MapReduce后的結(jié)果將全部是double!
3.一些附加操作
MapReduce的簡單原理很簡單,關(guān)鍵是靈活運用。現(xiàn)在我舉幾個我自己經(jīng)歷的例子:
(1)將查詢放入MapReduce。
在前面的runCommand中添加參數(shù)。比如我要查詢所有男生,我就加.查詢:{'isman' true},
(2)結(jié)果的數(shù)據(jù)類型轉(zhuǎn)換。
使用Finalize函數(shù)(該函數(shù)在Reduce函數(shù)之后調(diào)用,它將對所有鍵的Reduce結(jié)果執(zhí)行最終操作)。比如我在后臺調(diào)用api后想要的是int數(shù)據(jù),而不是double數(shù)據(jù)。
然后您可以添加Finalize函數(shù):
一.2最終確定:函數(shù)Finalize(key,reduced){ 3 reduce。count=number int(減少。計數(shù));四退貨減少;5 },6 .這樣,
(3)時間類型
因為mongodb有日期類型,所以存儲時間的格式和查詢時間的格式可能會不一致(尤其是你的mongodb是遠程部署,多人協(xié)作開發(fā)的時候),會導(dǎo)致無法根據(jù)時間條件找到數(shù)據(jù)的問題。我的建議是,
長形式的直接存儲時間(過去的秒),那么這個差異問題就不再存在了。