user29578
user29578

Reputation: 689

Run map reduce for all keys in collections - mongodb

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

Answers (1)

Markus W Mahlberg
Markus W Mahlberg

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

Related Questions