如何使用mapReduce将以下SQL查询转换为mongoDB
SELECT mobile, SUM( amount ),count(mobile) as noOfTimesRecharges
FROM recharge
WHERE recharge_date between '2015-02-26' AND '2015-03-27'
GROUP BY mobile
having noOfTimesRecharges > 0 and noOfTimesRecharges < 5
我试过了
db.users.mapReduce(
function(){
emit(this.mobile,this.amount);
},
function(k,v){
return Array.sum(v)
},
{
query:{
recharge_date:{$gte:ISODate("2014-06-17"),$lte:ISODate("2014-06-20")}
},
out:"one_month_data"
}).find();
给了我结果但不给了计数。
答案 0 :(得分:5)
所以你可能真的想要aggregation framework。它在本机代码操作中运行,比从mapReduce
的JavaScript评估中获得的速度快得多。
db.users.aggregate([
{ "$match": {
"recharge_date": {
"$gte": ISODate("2014-06-17"),
"$lte": ISODate("2014-06-20")
}
}},
{ "$group": {
"_id": "$mobile",
"amount": { "$sum": "$amount" },
"count": { "$sum": 1 }
}},
{ "$match": {
"count": { "$gt": 1, "lt": 5 }
}}
{ "$out": "newCollection" }
],
{ "allowDiskUse": true }
)
编码效率更高,更简单。
另请查看SQL to agregation mapping chart以获取常见示例。
如果你确实需要mapReduce(你可能不需要),那么正确的方法是:
db.users.mapReduce(
function() {
emit( this.mobile, { "amount": this.amount, "count": 1 } );
},
function(key,values) {
var doc = { "amount": 0, "count": 0 };
values.forEach(function(value) {
doc.amount += value.amount;
doc.count += value.count;
};
return doc;
},
{
"out": { "replace": "newCollection" },
"query": {
"recharge_date": {
"$gte": ISODate("2014-06-17"),
"$lte": ISODate("2014-06-20")
}
}
}
)
但是,对于“限制”结果,您没有像使用聚合管道那样得到相同的情况,而无需对结果集合进行额外处理。