Function Nested Group with MongoDB

I am new to MongoDB, a long time dude of MySQL and am in a small checkpoint.

Given the following data:
TeamID Day OrderAmount
100 4/1 50
100 '4/1 40
200 4/2 50
100 4/2 20

I am trying to find the average order per team per day. I can make a simple query using the mapReduce function to make a group using TeamId and Day. So now I have:

TeamID AvgAmount
100 4/1 45
200 50
100 20

Now I'm trying to drill this data to get the average order amount per team per day, which will be:

Day AvgAmount
4/1 47.5
4/2 35

I can do this easily with MySQL, but it's hard for me to figure out how to do this with MongoDB without doing it manually in the application side, and not doing it with MongoDB.

+3
source share
2 answers

You can calculate these aggregates using the map-reduce or group () function . I use group () because it is a bit simpler and faster, however you should use map-reduce if you need to distribute the request across a cluster cluster.

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

On command, 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 collapse daily aggregates, simply 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 }
});
+4
source

. , - , 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;
    }
0

All Articles