资讯专栏INFORMATION COLUMN

巧用 db.system.js 提升20% 开发效率

flybywind / 1135人阅读

摘要:开门见山,是我造的,哈哈,为的就是让各位能够对引起注意。执行一次,,果然就可以使用我们自定义的函数了。到这里,我们基本就可以实现一个自定义的的强大组合了上海小胖原创地址欢迎各位大神前来评论。每周五,敬请期待,上海小胖独更。

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

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

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;imaxValue)
        {
            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] 原创地址: https://segmentfault.com/u/shanghaixiaopang/articles

欢迎各位大神前来评论。

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

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


Implementing Aggregation Functions in MongoDB ↩

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/19074.html

相关文章

  • 巧用 Img / JavaScript 采集页面数据

    摘要:日志服务提供就是为解决以上轻量级埋点采集场景而生,我们可以在分钟时间内完成埋点和数据上报工作。服务功能包括实时采集与消费。 摘要: 当我们有一个新内容时(例如新功能、新活动、新游戏、新文章),作为运营人员总是迫不及待地希望能尽快传达到用户,因为这是获取用户的第一步、也是最重要的一步。 点此查看原文:http://click.aliyun.com/m/40929/ 我们发送重要邮件时为...

    sunny5541 评论0 收藏0
  • 巧用 Img / JavaScript 采集页面数据

    摘要:日志服务提供就是为解决以上轻量级埋点采集场景而生,我们可以在分钟时间内完成埋点和数据上报工作。服务功能包括实时采集与消费。 摘要: 当我们有一个新内容时(例如新功能、新活动、新游戏、新文章),作为运营人员总是迫不及待地希望能尽快传达到用户,因为这是获取用户的第一步、也是最重要的一步。 点此查看原文:http://click.aliyun.com/m/40929/ 我们发送重要邮件时为...

    WrBug 评论0 收藏0
  • 巧用开源软件做好企业管理

    摘要:从管事到管人的根本转变其实,除了上述领域,开源软件在企业管理中已成为不可或缺的工具,在人,财,物等资源的管理上发挥着越来越重要的作用。也正因此,开源软件受到了很多企业的欢迎。 开源软件的应用领域广泛 我们通常所说的开源软件,是指所有公开源代码的软件。也就是说公众可以通过极低的成本(如仅仅访问互联网而无需其他额外费用)获得该软件的源代码,并可自行修改源代码以满足自己的特殊需求。 开源软件...

    novo 评论0 收藏0
  • 巧用开源软件做好企业管理

    摘要:从管事到管人的根本转变其实,除了上述领域,开源软件在企业管理中已成为不可或缺的工具,在人,财,物等资源的管理上发挥着越来越重要的作用。也正因此,开源软件受到了很多企业的欢迎。 开源软件的应用领域广泛 我们通常所说的开源软件,是指所有公开源代码的软件。也就是说公众可以通过极低的成本(如仅仅访问互联网而无需其他额外费用)获得该软件的源代码,并可自行修改源代码以满足自己的特殊需求。 开源软件...

    余学文 评论0 收藏0
  • 巧用开源软件做好企业管理

    摘要:从管事到管人的根本转变其实,除了上述领域,开源软件在企业管理中已成为不可或缺的工具,在人,财,物等资源的管理上发挥着越来越重要的作用。也正因此,开源软件受到了很多企业的欢迎。 开源软件的应用领域广泛 我们通常所说的开源软件,是指所有公开源代码的软件。也就是说公众可以通过极低的成本(如仅仅访问互联网而无需其他额外费用)获得该软件的源代码,并可自行修改源代码以满足自己的特殊需求。 开源软件...

    huhud 评论0 收藏0

发表评论

0条评论

flybywind

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<