Let's say I have a dataset like the following:
{ "_id" : ObjectId("4dd51c0a3f42cc01ab0e6506"), "views" : 1000, "status" : 1 }
{ "_id" : ObjectId("4dd51c0e3f42cc01ab0e6507"), "views" : 2000, "status" : 1 }
{ "_id" : ObjectId("4dd51c113f42cc01ab0e6508"), "views" : 3000, "status" : 1 }
{ "_id" : ObjectId("4dd51c113f42cc01ab0e6508"), "views" : 4000, "status" : 0 }
What is the fastest way (performance-wise) to get the average number of views for all documents with a status of 1? Is Map/Reduce required for something basic like this, or is there another way?
The aggregation query takes ~80ms while the find query takes 0 or 1ms.
We can manually verify this is correct by calculating the average of the points values by hand: Average of Points: (30 + 30 + 20 + 25 + 25) / 5 = 26.
Aggregation wins where the volume of data returned is much less than the original data or where you don't have the skill to build fast client side aggregations. I hope it answers your query.
Use group: http://www.mongodb.org/display/DOCS/Aggregation
you need a counter for the documents and another for the sum of views. In finalize you just do a division on these two numbers.
db.test.group(
{ cond: {"status": 1}
, initial: {count: 0, total:0}
, reduce: function(doc, out){ out.count++; out.total += doc.views }
, finalize: function(out){ out.avg = out.total / out.count }
} );
Faster way to get average in any case - precalculate it(probably you can do this in background) and create extra field/collection to store it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With