Rodrigo Dias Rodrigo Dias - 2 months ago 14
Ruby Question

mongodb count equal object

I have a MongoDB database with documents that contain a filter field. The documents looks like this:

"_id": ObjectId("503208f5b5db0135387d9249"),
"name": "name1",
"filter": "facebook"
} {
"_id": ObjectId("503208f5b5db0135387d9249"),
"name": "name2",
"filter": "twitter"
"_id": ObjectId("503208f5b5db0135387d9249"),
"name": "name3",
"filter": "twitter"

And I want to count by type. This example should be like this:

facebook => 1, twitter => 2

With ruby code, counting is very slow.

The filter is a String which could be anything. E.g:

{facebook : 1203, twitter : 201, wherever : 200, othertype : 400}

I am using mongo mapper (ruby driver).


Finally it's working. here's the code for ruby driver:

def map
emit(this.plataforma, 1);
def reduce
function(prev, current) {
var n = 0;
return n;

def build
Mention.collection.map_reduce(map, reduce, :query => {})

Answer Source

This is similar to:

Where by it shows how you could run an MR like so:

var map = function(){

var reduce  = function(previous,current){
    var count = 0;

    for (index in current) {
        count += current[index];

    return count;

Which will then output, to another collection (or inline if you want) documents of the format:

    _id: facebook,
    value: 1,
    _id: twitter,
    value: 2

This is written in MongoDBs console language which is JS. MongoDB has a built in JavaScript parser (spidermonkey) which can parse MR functions. From Ruby you would encapsulate your functions like so:

map = "function() { emit(this.filter, 1); }"

And then run the MR like so:

col.map_reduce(map, reduce,
            :out => 'summary_collection',
            :raw => true

And then you would just query summary collection for that filter by supplying the string representation as the _id or do a simple find() to get all results.