Frage

How can I run aggregate, min, max, sum and friends on embedded docs?

For example:

Get the average cost of ALL events that a district has, where they are pretty deeply embedded.

District.schools.all.events.all.costs.avg(:value)

Obviously doesn't work.

District.avg('schools.events.costs.value')

Neither does that. It gives this error message:

Mongo::OperationFailure: Database command 'group' failed: (errmsg: 'exception: reduce
invoke failed: JS Error: TypeError: obj.schools 
has no properties reduce setup:1'; code:   '9010'; ok: '0.0').

So is it possible or do I need to write my own map/reduce functions?

War es hilfreich?

Lösung

Yes, MapReduce would work. You could also use cursors to process a query result. Like:

min = 99999999;
max = -99999999;
sum = 0;
count = 0
db.School.find({}).forEach(function(s) {
    if (s.first.events.first.cost < min)
        min = s.first.events.first.cost;
    if (s.first.events.first.cost > max)
        max = s.first.events.first.cost;
    sum += s.first.events.first.cost;
    ++count;
});

You now have the min and max and can calculate the average and mean from the sum and count.

Mongodb does not have the ability to calculate the aggregate functions in its query language directly. Actually, that statement is not entirely true, since there is the count() function to count the number of results returned by a query, and there is the group() function. But the group function is a lot like a MapReduce, and cannot be used on sharded databases. If you are interested in the group function, see: http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Group

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top