Created
February 22, 2011 10:18
-
-
Save boj/838468 to your computer and use it in GitHub Desktop.
MongoMapper MapReduce Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
you can use the group method of mongodb from rails in a similar way?
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
Modified version to handle the MapReduce output collection, and better options handling.