python js 效率_巧用 db.system.js 提升20% 开发效率
開門見山,20%是我造的,哈哈,為的就是讓各位mongoer能夠對db.system.js collection 引起注意。
這個也是在我最近瀏覽InfoQ 的時候,看到一篇關于MongoDB 文章
system.js
先來看下官文給出的解釋:
.system.js
The .system.js collection holds special JavaScript code for use in server side JavaScript. See Store a JavaScript Function on the Server for more information.
解釋很簡單,馬上就進入實操環節
db.system.js.save(
{
_id: "echoFunction",
value : function(x) { return x; }
}
)
但是并沒有任何效果,shell里表示,echoFunction undefined.
在查看 db.system.js 確實有一條記錄
> db.system.js.find({_id: 'echoFunction'}).pretty()
{
"_id" : "echoFunction",
"value" : {
"code" : "function (x) { return x; }"
}
}
繼續查看doc,原來還需要通過 loadServerScripts 函數 load 進數據字典,這個操作就有點像我們在linux 環境中 source ~/.bash_profile 一樣了。
執行一次,db.loadServerScripts() , 果然就可以使用我們自定義的函數了。
那問題來了,如何提升我們的工作效率呢?
在MongoDB 中,雖然有 $sum, $avg 等一系列的pipeline,但是,對于DBA也好,Developer 也罷,許多的報表、統計aggregation 并不能完全代勞,mapReduce 就是為了這個時候而上的,那每次都要去寫一個function 去 sum,去 avg 總顯得在反復造輪子,因此我們完全可以在這種情況下,在 db.system.js 中加入我們常用的統計函數,比如 sum, avg, max, min 等等。
這里我就給出自己常用的函數供大家參考:
SUM
db.system.js.save( { _id : "Sum" ,
value : function(key,values)
{
var total = 0;
for(var i = 0; i < values.length; i++)
total += values[i];
return total;
}});
AVERAGE
db.system.js.save( { _id : "Avg" ,
value : function(key,values)
{
var total = Sum(key,values);
var mean = total/values.length;
return mean;
}});
MAX
db.system.js.save( { _id : "Max" ,
value : function(key,values)
{
var maxValue=values[0];
for(var i=1;i
{
if(values[i]>maxValue)
{
maxValue=values[i];
}
}
returnmaxValue;
}});
MIN
db.system.js.save( { _id : "Min" ,
value : function(key,values)
{
var minValue=values[0];
for(var i=1;i
{
if(values[i]
{
minValue=values[i];
}
}
return minValue;
}});
VARIANCE
db.system.js.save( { _id : "Variance" ,
value : function(key,values)
{
var squared_Diff = 0;
var mean = Avg(key,values);
for(var i = 0; i < values.length; i++)
{
var deviation = values[i] - mean;
squared_Diff += deviation * deviation;
}
var variance = squared_Diff/(values.length);
return variance;
}});
STD DEVIATION
db.system.js.save( { _id : "Standard_Deviation"
, value : function(key,values)
{
var variance = Variance(key,values);
return Math.sqrt(variance);
}});
MapReduce
那么接下來我們就用Map-Reduce來結合之前的自定義聚合函數來做詳解。(這里權當各位大佬熟悉Map-Reduce了)
引入demo data
{ "_id" : ObjectId("4f7be0d3e37b457077c4b13e"), "_class" : "com.infosys.mongo.Sales", "orderId" : 1, "orderDate" : "26/03/2011",
"quantity" : 20, "salesAmt" : 200, "profit" : 150, "customerName" : "CUST1", "productCategory" : "IT", "productSubCategory" : "software",
"productName" : "Grad", "productId" : 1 }
{ "_id" : ObjectId("4f7be0d3e37b457077c4b13f"), "_class" : "com.infosys.mongo.Sales", "orderId" : 2, "orderDate" : "23/05/2011",
"quantity" : 30, "salesAmt" : 200, "profit" : 40, "customerName" : "CUST2", "productCategory" : "IT", "productSubCategory" : "hardware",
"productName" : "HIM", "productId" : 1 }
{ "_id" : ObjectId("4f7be0d3e37b457077c4b140"), "_class" : "com.infosys.mongo.Sales", "orderId" : 3, "orderDate" : "22/09/2011",
"quantity" : 40, "salesAmt" : 200, "profit" : 80, "customerName" : "CUST1", "productCategory" : "BT", "productSubCategory" : "services",
"productName" : "VOCI", "productId" : 2 }
{ "_id" : ObjectId("4f7be0d3e37b457077c4b141"), "_class" : "com.infosys.mongo.Sales", "orderId" : 4, "orderDate" : "21/10/2011",
"quantity" : 30, "salesAmt" : 200, "profit" : 20, "customerName" : "CUST3", "productCategory" : "BT", "productSubCategory" : "hardware",
"productName" : "CRUD", "productId" : 2 }
{ "_id" : ObjectId("4f7be0d3e37b457077c4b142"), "_class" : "com.infosys.mongo.Sales", "orderId" : 5, "orderDate" : "21/06/2011",
"quantity" : 50, "salesAmt" : 200, "profit" : 20, "customerName" : "CUST3", "productCategory" : "BT", "productSubCategory" : "hardware",
"productName" : "CRUD", "productId" : 1 }
創建聚合函數Sum
db.system.js.save({
_id : "Sum" ,
value: function(key,values) {
var total = 0;
for(var i = 0; i < values.length; i++)
total += values[i];
return total;
}
});
結合Sum 聚合函數執行Map-Reduce
db.runCommand(
{
mapreduce: "sales" ,
map: function() {
emit({
key0:this.productCategory,
key1:this.productSubCategory,
key2:this.productName
},
this.salesAmt
);
},
reduce: function(key, values) {
var result = Sum(key, values);
return result;
},
out: {inline: 1}
}
)
這里,就直接把結果輸出的stdout 了,如果需要可以指定collection,將我們的Map-Reduce結果存儲下來。
來看一下結果
{
"results" : [
{
"_id" : {
"key0" : "BT",
"key1" : "hardware",
"key2" : "CRUD"
},
"value" : 400
},
{
"_id" : {
"key0" : "BT",
"key1" : "services",
"key2" : "VOCI"
},
"value" : 200
},
{
"_id" : {
"key0" : "IT",
"key1" : "hardware",
"key2" : "HIM"
},
"value" : 200
},
{
"_id" : {
"key0" : "IT",
"key1" : "software",
"key2" : "Grad"
},
"value" : 200
}
],
"timeMillis" : 14,
"counts" : {
"input" : 5,
"emit" : 5,
"reduce" : 1,
"output" : 4
},
"ok" : 1
}
這里可以看到,我們的Sum 函數已經將emit 過后的 "productCategory" : "BT", "productSubCategory" : "hardware", "productName" : "CRUD" 這組數據的 salesAmt 累加了。
到這里,我們基本就可以實現一個自定義的Function + Map-Reduce 的強大組合了!
歡迎各位大神前來評論。
每周五,敬請期待,上海小胖[MiracleYoung] 獨更。
如果夏雨荷還在大明湖畔等著我的話,我就不更了。
總結
以上是生活随笔為你收集整理的python js 效率_巧用 db.system.js 提升20% 开发效率的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 响应式编程优点 有效_Reactive(
- 下一篇: python爬取百度贴吧xpath_爬虫