博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
巧用 db.system.js 提升20% 开发效率
阅读量:6007 次
发布时间:2019-06-20

本文共 6280 字,大约阅读时间需要 20 分钟。

开门见山,20%是我造的,哈哈,为的就是让各位mongoer能够对db.system.js collection 引起注意。

这个也是在我最近浏览InfoQ 的时候,看到一篇关于MongoDB 文章的时候意识到的问题,随后和开发们沟通了下,结果是对这个collection 不是很了解,遂生此文。

system.js

先来看下官文给出的解释:

<database>.system.js

The <database>.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
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
  • 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] 原创地址:

欢迎各位大神前来评论。

每周五,敬请期待,上海小胖[MiracleYoung] 独更。

如果夏雨荷还在大明湖畔等着我的话,我就不更了。


转载地址:http://cspmx.baihongyu.com/

你可能感兴趣的文章
NodeJS简单爬虫
查看>>
小猿圈分享-主流浏览器图片反防盗链方法总结
查看>>
Vue双向绑定原理
查看>>
如何聪明地利用待办事项 APP 完成任务
查看>>
4年程序员十面阿里终拿下offer,评级P6
查看>>
为什么我说IPFS社区从卖矿机开始,就是错的
查看>>
二叉树的遍历
查看>>
RPA机器人,银行业开挂的新武器
查看>>
javascript 周报 435 期
查看>>
10分钟快速进阶rollup.js
查看>>
java版b2b2c社交电商spring cloud分布式微服务(二)服务消费者(rest+ribbon)
查看>>
iOS第三方平台集成组件化
查看>>
404 Sum of Left Leaves
查看>>
提供SaaS Launchkit,快速定制,一云多端等能力,一云多端将通过小程序云实现...
查看>>
java b2b2c SpringCloud电子商务平台
查看>>
(十三)企业分布式微服务云SpringCloud SpringBoot mybatis-断路器聚合监控(Hystrix Turbine)...
查看>>
热更新
查看>>
亿万富翁Calvin Ayre梭哈BCH!
查看>>
map/reduce之间的shuffle,partition,combiner过程的详解
查看>>
ubuntu 手动配置interface上网
查看>>