mongodb mapreduce, 实现 select sum(a*b) from test

浏览:43日期:2023-06-27

问题描述

首先介绍user collection

user {’username’:, ’age’:, ’account’:}下面是正常的group_by 和count实现

//SQL实现

select username,count(sku) from user group by username

//MapReduce实现

map=function (){ emit(this.username,{count:1})}reduce=function (key,values){ var cnt=0; values.forEach(function(val){ cnt+=val.count;}); return {'count':cnt}}

//执行mapreduce

db.test.mapReduce(map,reduce,{out:'mr1'})

db.mr1.find()

{ '_id' : 'Joe', 'value' : { 'count' : 416 } }{ '_id' : 'Josh', 'value' : { 'count' : 287 } }{ '_id' : 'Ken', 'value' : { 'count' : 297 } }然后

//SQL实现

select sum(age * account) from user

//MapReduce实现,或者用其他方法实现也可以???????????????????

问题解答

回答1:

通常我们会建议避免在MongoDB中使用map/reduce,性能表现并不十分理想。大部分时候可以使用aggregation framework取代,特别是只涉及一个表的时候。

db.user.aggregate([ {$group: {_id: ’$username’, count: {$sum: 1}}}]);

具体语法就请自己查阅aggregation的语法咯。a*b会比较复杂一点,你实际需要的是每条记录的a*b的值(pipline1),然后求和(pipline2):

db.user.aggregate([ {$group: {_id: '$username', temp_result: {$multiply: ['$age', '$account']}}}, {$group: {_id: null, result: {$sum: '$temp_result'}}}]);回答2:

var map = function(){

emit('sum',this.age*this.account);}

var reduce = function(key,values){

var cnt = 0;values.forEach(function(val){cnt+=val;});return {'sumAll':cnt};}

以上定义完成后执行:db.user.mapReduce(map,reduce,{out:'mr1'});再查询mr1的文档:db.mr1.find();将会获得结果

相关文章: