MongoDB Map & Reduce with Date filter

We are using MongoDB as primary DB at VersionEye, together with MongoID. Software package is a document in the “products” collection. These products collections has a subcollection with “versions”. Assume we want to know how many versions/artifacts existed for a given language to a given time?

That is not a simple query in MongoDB. This kind of queries can be handled with Map & Reduce. With Map & Reduce you can execute JavaScript on DB Level. Here is the current solution:



border = until_date.at_midnight + 1.day

map = %Q{
  function() {
    if ( this.versions == null || this.versions.count == 0 ) return;

    that_day = new ISODate("#{border.iso8601}");
    for (var version in this.versions){
      created = this.versions[version].created_at
      if (created != null && created.getTime() < that_day.getTime()){
        emit( this.versions[version]._id, { count: 1 } );
      }
    }
  }
}

reduce = %Q{
  function(key, values) {
    var result = { count: 0 };
    values.forEach(function(value) {
      result.count += value.count;
    });
    return result; 
  }
}

Product.where(:language => language, :created_at.lt => border ).map_reduce(map, reduce).out(inline: true)

The tricky part was this line:

that_day = new ISODate("#{border.iso8601}");

To find out how to convert a Ruby Date object into the JavaScript Date object.

Otherwise you have to know that even through you are iterating over a versions collection you can not access the version object through “version”! You have to access it this way:

this.versions[version]

Otherwise it works fine 🙂

Installing Ruby on Mac OS X

On Mac OS X Ruby 1.8.X is already pre-installed. But if you want to have the newest version 1.9.X you have to install it again. I assume that you installed already XCode and MacPorts on your machine. Than you have update your MacPorts

sudo port selfupdate

All right. Now you can install the newest version.

sudo port install ruby19

That’s it. Now you have to versions of Ruby on your computer. Check the version.

ruby1.9 --version

You should see something like this here:

ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11]

First Steps with Ruby

I am a Java guy. I have nearly 10 years experience with Java. I have build high scale able Web Apps with Java, Spring, Struts, JSF, Hibernate, JDBC, Ant, Maven2, JUnit and some other crazy Frameworks.

Now I want to try out something new. I am playing around with Ruby, Rails, Gem, Rake and all the other Ruby Tools. My First impression. To install the newest version of Ruby and Rails on a Mac, it is a pain in the ass!

Ruby 1.8.2 is already pre installed on Mac OS X Snow Leopard. With MacPorts you can install pretty easy the version 1.9.1.

sudo port install ruby19

A more detailed tutorial you can find here: Tutorial

Over rubygems I fetched the newest version of the Rails Framework, 3.0.4. Then I try to use it, I get this Message:

Rails 3 doesn't officially support Ruby 1.9.1 since recent stable
 releases have segfaulted the test suite. Please upgrade to Ruby 1.9.2.

 You're running
 ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin10]

All right! No Problem. I am a big boy. I can install the newest version 1.9.2 from the source code. Just download the sourcecode for Ruby 1.9.2 and compile & build it from the source:

./configure
make
make test
make install

The command “ruby –version” now shows me:

ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.6.0]

All right. Looks good. Trying again to use rails. “rails –version”. Still get the same Message:

Rails 3 doesn't officially support Ruby 1.9.1 since recent stable
 releases have segfaulted the test suite. Please upgrade to Ruby 1.9.2.

 You're running
 ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin10]

Hm. I am pretty sure I have version 1.9.2 on my Mac! How to tell Rails to use the newest version?

Any Ideas ???