对于MongoDB来说,我是一个很新的人,他是一个很长时间的MySQL人,而且遇到了一些障碍。
鉴于以下样本数据:
TeamID Day OrderAmount
100个4/1 50
100个4/1 40
200个4/2 50
100 4/2 20
我正在尝试查找每天的平均团队订单金额。我可以使用mapReduce函数进行一个简单的查询,通过TeamId& amp;天。所以现在我有:
TeamID日AvgAmount
100个4/1 45
200个4/2 50
100个4/2 20
现在我正在努力推广这些数据,以获得每个团队每天的平均订单金额,这将是:
日AvgAmount
4/1 47.5
4/2 35
我可以使用MySQL轻松完成这项工作,但是如果没有在应用程序端手动执行,而不是使用MongoDB进行操作,我很难弄清楚如何使用MongoDB执行此操作。
答案 0 :(得分:4)
您可以使用map-reduce或group()函数计算这些聚合。我正在使用group(),因为它更简单,更快,但如果需要在分片集群上分发查询,则应使用map-reduce。
首先加载数据:
db.orders.insert( { teamid: 100, date: "4/1", amount: 50 })
db.orders.insert( { teamid: 100, date: "4/1", amount: 40 })
db.orders.insert( { teamid: 200, date: "4/2", amount: 50 })
db.orders.insert( { teamid: 100, date: "4/2", amount: 20 })
每个团队,每天:
db.orders.group({
key: { teamid: true, date: true },
reduce: function(doc, out) { out.sum += doc.amount; out.count++; },
initial: { sum: 0, count: 0 },
finalize: function(out) { out.average = out.sum / out.count }
});
要汇总每日汇总数,只需更改密钥:
db.orders.group({
key: { date: true },
reduce: function(doc, out) { out.sum += doc.amount; out.count++; },
initial: { sum: 0, count: 0 },
finalize: function(out) { out.average = out.sum / out.count }
});
答案 1 :(得分:0)
经过一番研究,我得出了一个解决方案。我不满足于它是最优化的解决方案,因为它是MongoDB的新手并且映射/减少思维,所以如果其他人有更好的东西,请纠正我。具体来说,我无法获得一定长度的arr_team对象,所以我必须有一个递增的计数器。
减少功能:
function(doc, prev) {
var retVal = {team_count: 0, day_total: 0};
if(!prev.arr_team[doc.team_id]) {
prev.arr_team[doc.team_id] = 0;
prev.team_count++;
}
prev.arr_team[doc.team_id]++;
prev.order_count++;
if(doc.total_amount)
prev.total_amount += doc.total_amount
return retVal;
}
敲定:
function(out) {
out.avg_team_order_amount = out.total_amount/out.team_count;
}