Created
March 28, 2012 21:40
-
-
Save mrdanadams/2230825 to your computer and use it in GitHub Desktop.
db.eval() and server-side updates on MongoDB with the Ruby driver
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
# Records the vote against 2 items. | |
# Both parameters are strings | |
def record_votes(winner_id, loser_id) | |
# grab the connection from the underlying driver | |
db = Mongoid::Config::master | |
# a future improvement would be to store this away somewhere, perhaps as a constant | |
# note: javascript comments added for the post: they are not in the real code | |
f = """ | |
function(winner_id, loser_id) { | |
// will update one of the documents based on if it won the vote or not | |
var update = function(id, win) { | |
var doc = db.items.findOne({_id: ObjectId(id)}); | |
if (!doc) return; // just ignore if can't find it | |
// updated automatically be Mongoid but we need to do it ourselves here | |
doc.updated_at = new Date(); | |
// the simple updates that could have been done in-place | |
doc.votes++; | |
if (win) doc.wins++; else doc.losses++; | |
// stats calculations. the actual calculation is not important. | |
doc.percent_wins = Math.round(doc.wins / doc.votes * 100); | |
doc.percent_losses = Math.round(doc.losses / doc.votes * 100); | |
doc.rank = doc.percent_wins * (doc.votes >= #{ItemsController::VOTE_THRESHOLD} ? 100 : 10); | |
db.items.save(doc); | |
} | |
// perform separate updates on each document | |
update(winner_id, true); | |
update(loser_id, false); | |
} | |
""" | |
# note $eval has to be first | |
db.command({:$eval => f, args: [winner_id, loser_id], nolock: true}) | |
end |
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
> db.runCommand({ $eval: function(abool) { return abool; }, args: [false], nolock: true }); | |
Tue Nov 22 11:55:02 [conn1] query test.$cmd ntoreturn:1 command: { $eval: function (abool) { | |
return abool; | |
}, args: [ false ], nolock: true } reslen:62 183ms | |
{ "retval" : false, "ok" : 1 } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment