map-reduce using mongoid

It took me a while to work out how to use map-reduce in Ruby using mongoid so I thought I’d share it here in-case it helps anyone else get there quicker. I start out with a model that includes Mongoid::Document:

To map-reduce across the collection I need to define a map and reduce function in javascript then run the on the collection:

I can roll this into my VisitorSession model:

This obviously makes it easier to call:

>> VisitorSession.first(:conditions => {:project_id => '2f5178'}).visits_for_project
=> 1

Tagged ,

5 thoughts on “map-reduce using mongoid

  1. Sorry to be a smartass, but EOF is end-of-file while you probably mean EOS end-of-string.

  2. Will says:

    The heredoc delimiter is an arbitrary string so I could equally have used:

    map = <<ThomasRKollIsASmartass
      bla
      yak
      bla
      etc.
    ThomasRKollIsASmartass

    Of course It would make sense to use something descriptive, so End Of Function will have to do :)

  3. That’s a useful post, thanks. It’s made me realise that map/reduce won’t solve my problem, as I’d need my map function to iterate over all the embededded documents in a single object. Time to write an iterator, I think…

    Also, I approve of your use of EOF. It’s a convention.
    EOF

  4. khelll says:

    for the sake of readability I use this style of code:

    map = <<MAP
    function() {
    ……
    }
    MAP

    reduce = <<REDUCE
    function(key, values) {
    …….
    };
    REDUCE

  5. great example, but it doesn’t seem to be the correct way to pre-filter your collection:

    if (this.project_id == ‘#{project_id}’) {

    and the correct way is to use a query option when calling mapreduce. Mongoid supports options as 3rd parameter in this function (as in js documentation).

    It won’t use index in your example, but with this correction – it will.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.