使用MongoDB的嵌套分组函数
我是MongoDB的新手,MySQL的老手,我遇到了一个小障碍 给定以下示例数据:使用MongoDB的嵌套分组函数,mongodb,mongoid,mongodb-ruby,Mongodb,Mongoid,Mongodb Ruby,我是MongoDB的新手,MySQL的老手,我遇到了一个小障碍 给定以下示例数据: TeamID日订单金额 1004/150 1004/140 2004/250 1004/220 我试图找到团队每天的平均订单量。我能够使用mapReduce函数进行简单查询,以使用TeamId和Day进行分组。所以现在我有: TeamIDDayAvgAmount 1004/145 2004/250 1004/220 现在,我尝试将这些数据汇总,以获得每个团队每天的平均订单量,即: DayAvgAmount 4/1
TeamID日订单金额
1004/150
1004/140
2004/250
1004/220 我试图找到团队每天的平均订单量。我能够使用mapReduce函数进行简单查询,以使用TeamId和Day进行分组。所以现在我有: TeamIDDayAvgAmount
1004/145
2004/250
1004/220
现在,我尝试将这些数据汇总,以获得每个团队每天的平均订单量,即: DayAvgAmount
4/147.5
4/235
我可以用MySQL轻松做到这一点,但我很难弄清楚如何用MongoDB做到这一点,而不是用MongoDB,而不是在应用程序端手动完成 您可以使用map reduce或函数计算这些聚合。我使用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 }
});
经过一番研究,我终于想出了一个解决办法。我不满意它是最优化的解决方案,因为它是MongoDB和map/reduce思想的新手,所以如果其他人有更好的解决方案,请纠正我。具体来说,我无法获得arr_团队对象的长度,因此我必须有一个递增的计数器 减少功能:
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;
}
谢谢Chris,但是你的最后一个例子不能解释一个团队在同一天有两个订单。我能做到的是,它会以你拥有它的方式数到两次。有没有一种方法可以使用某种散列数据类型来跟踪TeamID当天已经下了一个订单,这样我就不会把团队数两次了?@james,你能为你需要的结果发布相应的SQL吗?嗨,Chris,谢谢你尝试一下,请看下面我对我所寻找的答案。