MongoDB SUM 求和两大方法

0:背景:

最近在做数据统计部分,数据是放在MongoDB的,我们一开始的方法是从MongoDB中将数据取出,在PHP中做运算,后面发现数据量大的时候,太慢了,120W的数据差不多要花30秒,后面实在受不了,于是打算使用MapReduce重构。

1:MapReduce:

$db->command([
    'mapreduce' => 'orders',
    'map' => 'function(){emit("money",this.money)}',
    'reduce' => 'function(key, values){return Array.sum(values)}',
    'query' => $map,
    'out' => 'total_money'
]);
$re = $collection->selectCollection('total_money')->find();

但是用MapReduce后,性能提升不明显,目测只有10%左右。可能得益于省去网络的传输成本。

引用

1.group(先筛选再分组,不支持分片,对数据量有所限制,效率不高)

2.mapreduce(基于js引擎,单线程执行,效率较低,适合用做后台统计等)

3.aggregate(推荐) (如果你的PHP的mongodb驱动版本需>=1.3.0,推荐你使用aggregate,性能要高很多,并且使用上要简单些,不过1.3的目前还不支持账户认证模式,可以通过http://pecl.php.net/package/mongo查看更新日志和Bug)

后面发现,楼主的mongodb驱动刚好好能用aggregate,所以果断使用aggregate。

2:aggregate

$collection->aggregate([
    ['$match' => $map],
    ['$group' => [
        '_id' => null,
        'total_money' => ['$sum' => '$money'],
        'total_money_usd' => ['$sum' => '$money_usd']
    ]]
]);

由于楼主的MongoDB比较旧,所以不能再 $project 中调用 $sum(可以点我看看官方文档)。可以可贺的是,120w数据从原来的30秒下降到18秒,体验大大提升。领导看数据汇总也终于不用等半天了,下一步就是搞清楚分片以及升级一下MongoDB,看看有没有再提升的空间。

    原文作者:芳君君
    原文地址: https://www.jianshu.com/p/355d6ce01391
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞