Skip to content

Instantly share code, notes, and snippets.

@boj
Created February 22, 2011 10:18
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boj/838468 to your computer and use it in GitHub Desktop.
Save boj/838468 to your computer and use it in GitHub Desktop.
MongoMapper MapReduce Example
class Score
include MongoMapper::Document
key :user_id, ObjectId, :index => true
key :stage, String, :index => true
key :score, Integer
timestamps!
def self.high_score_map
<<-MAP
function() {
emit(this.stage, { user_id : this.user_id, score: this.score });
}
MAP
end
def self.high_score_reduce
<<-REDUCE
function(k, v) {
var top = 0;
var user_id = '';
for (var i in v) {
if (v[i]["score"] > top) {
top = v[i]["score"];
user_id = v[i]["user_id"];
}
}
return { user_id: user_id, score: top };
}
REDUCE
end
def self.high_score_build(opts)
Score.collection.map_reduce(high_score_map, high_score_reduce, opts).find()
end
def self.high_score(opts={})
data = []
Score.high_score_build(opts).each do |score|
data << { :user_id => score["value"]["user_id"], :stage => score["_id"], :score => score["value"]["score"] }
end
data
end
def self.high_score_daily(opts={})
opts[:query][:created_at] = { "$gt" => Time.now - 1.day }
Score.high_score(opts)
end
def self.high_score_weekly(opts={})
opts[:query][:created_at] = { "$gt" => Time.now - 1.week }
Score.high_score(opts)
end
def self.high_score_monthly(opts={})
opts[:query][:created_at] = { "$gt" => Time.now - 1.month }
Score.high_score(opts)
end
end
class TopScore
include MongoMapper::Document
key :_id, String
key :value, Hash
def self.compute_top_scores(opts={})
opts[:out] = "top_scores"
Score.high_score(opts)
end
end
@boj
Copy link
Author

boj commented Mar 2, 2011

Modified version to handle the MapReduce output collection, and better options handling.

@juanpabloaj
Copy link

you can use the group method of mongodb from rails in a similar way?

@boj
Copy link
Author

boj commented May 22, 2011

I don't use Rails these days, and I don't think you would want to be sorting potentially millions of documents in Ruby code.

If you meant the mongodb group command exposed by a client driver, it didn't give the power to sort the way I wanted, thus the map reduce method.

It's too bad this code never made it to release, I was looking forward to seeing it in practice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment