Reputation: 689
i am using map reduce in mongodb to find out the number of orders for a customer like this
db.order.mapReduce(
function() {
emit (this.customer,{count:1})
},
function(key,values){
var sum =0 ;
values.forEach(
function(value) {
sum+=value['count'];
}
);
return {count:sum};
},
{
query:{customer:ObjectId("552623e7e4b0cade517f9714")},
out:"order_total"
}).find()
which gives me an output like this
{ "_id" : ObjectId("552623e7e4b0cade517f9714"), "value" : { "count" : 13 } }
Currently it is working for a single customer which is a key. Now i want this to run this map reduce query for all customers in order collection, and output the result for all like this single output. Is there any way through which I can do it for all customers in order?
Upvotes: 1
Views: 807
Reputation: 20703
Using a map/reduce for that simple task is a bit like using a (comparatively slow) sledgehammer to crack a nut. The aggregation framework was basically invented for this kind of simple aggregation (and can do a lot more for you!):
db.order.aggregate([
{ "$group":{ "_id":"$customer", "orders":{ "$sum": 1 }}},
{ "$out": "order_total"}
])
Depending on your use case, you can even omit the $out
stage and consume the results directly.
> db.orders.aggregate([{ "$group":{ "_id":"$customer", "orders":{ "$sum": 1 }}}])
{ "_id" : "b", "orders" : 2 }
{ "_id" : "a", "orders" : 3 }
Note that with very large collections, this most likely is not suitable, as it make take a while (but it should still be faster than a map/reduce operation).
For finding the number of orders of a single customer, you can use a simple query and use the cursor.count() method:
> db.orders.find({ "customer": "a" }).count()
3
Upvotes: 2