3

我是 MongoDB 的新手,长期使用 MySQL 的人,遇到了一个小障碍。

给定以下示例数据:
TeamID Day OrderAmount
100 4/1 50
100 4/1 40
200 4/2 50
100 4/2 20

我正在尝试查找每天的平均团队订单量。我可以使用 mapReduce 函数进行简单查询,以使用 TeamId 和 Day 进行分组。所以现在我有:

TeamID 日平均金额
100 4/1 45
200 4/2 50
100 4/2 20

现在我正在尝试汇总这些数据以获得每个团队每天的平均订单量,即:

天平均金额
4/1 47.5
4/2 35

我可以用 MySQL 轻松地做到这一点,但是我很难弄清楚如何用 MongoDB 做到这一点,而不是在应用程序端手动完成,而不是用 MongoDB 完成。

4

2 回答 2

4

You can calculate these aggregates with either map-reduce, or the group() function. I'm using group() because it's a bit simpler and faster, however you should use map-reduce if you need to distribute the query over a sharded cluster.

First load the data:

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 })

Per team, per day:

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 }
});

To roll up daily aggregates, just change the key:

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 }
});
于 2011-05-21T01:42:53.477 回答
0

经过一番研究,我能够想出一个解决方案。我不满意它是最优化的解决方案,因为它是 MongoDB 的新手和 map/reduce 思维,所以如果其他人有更好的东西,请纠正我。具体来说,我无法获得 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;
    }
于 2011-05-22T19:26:02.173 回答