diff --git a/HISTORY b/HISTORY index 9bb0813..b4401e0 100644 --- a/HISTORY +++ b/HISTORY @@ -1,3 +1,13 @@ +0.18 2009-11-25 +* Connections now support connection pooling. See http://api.mongodb.org/ruby/0.18/classes/Mongo/Connection.html#M000158 +* Deprecated :auto_reconnect option on connection; if the driver fails to + connect, it will automatically try to reconnect on the subsequent operation. + See http://www.mongodb.org/display/DOCS/Replica+Pairs+in+Ruby +* Added Collection#map_reduce helper (Christos Trochalakis) +* Deprecated DB#db_command in favor of DB#command. +* Removed deprecated old sort options, :offset, and Connection#clear. +* Lots of internal code restructuring for better maintainability. + 0.17.1 2009-11-17 * Index ordering fix * Notice to install mongo_ext diff --git a/README.rdoc b/README.rdoc index 9fc9f80..cd24a03 100644 --- a/README.rdoc +++ b/README.rdoc @@ -376,6 +376,9 @@ Sunny Hirai * Suggested hashcode fix for Mongo::ObjectID * Noted index ordering bug. +Christos Trochalakis +* Added map/reduce helper + = License Copyright 2008-2009 10gen Inc. diff --git a/lib/mongo/collection.rb b/lib/mongo/collection.rb index f0bb8c6..ab46c09 100644 --- a/lib/mongo/collection.rb +++ b/lib/mongo/collection.rb @@ -298,18 +298,28 @@ module Mongo @db.drop_collection(@name) end - def mapreduce(map, reduce, options={}) - case map - when Code - else - map = Code.new(map) - end - - case reduce - when Code - else - reduce = Code.new(reduce) - end + # Performs a map/reduce operation on the current collection. Returns a new + # collection containing the results of the operation. + # + # Required: + # +map+ :: a map function, written in javascript. + # +reduce+ :: a reduce function, written in javascript. + # + # Optional: + # :query :: a query selector document, like what's passed to #find, to limit + # the operation to a subset of the collection. + # :sort :: sort parameters passed to the query. + # :limit :: number of objects to return from the collection. + # :finalize :: a javascript function to apply to the result set after the + # map/reduce operation has finished. + # :out :: the name of the output collection. if specified, the collection will not be treated as temporary. + # :keeptemp :: if true, the generated collection will be persisted. default is false. + # :verbose :: if true, provides statistics on job execution time. + # + # For more information on using map/reduce, see http://www.mongodb.org/display/DOCS/MapReduce + def map_reduce(map, reduce, options={}) + map = Code.new(map) unless map.is_a?(Code) + reduce = Code.new(reduce) unless reduce.is_a?(Code) hash = OrderedHash.new hash['mapreduce'] = self.name @@ -317,16 +327,15 @@ module Mongo hash['reduce'] = reduce hash.merge! options - result = @db.db_command(hash) - if result["ok"] == 1 - return @db[result["result"]] - else - raise Mongo::OperationFailure, "map-reduce failed: #{result['errmsg']}" + result = @db.command(hash) + unless result["ok"] == 1 + raise Mongo::OperationFailure, "map-reduce failed: #{result['errmsg']}" end + @db[result["result"]] end + alias :mapreduce :map_reduce - # Perform a query similar to an SQL group by operation. - # + # Performs a group query, similar to the 'SQL GROUP BY' operation. # Returns an array of grouped items. # # :keys :: Array of fields to group by @@ -344,11 +353,7 @@ module Mongo hash[k] = 1 end - case reduce - when Code - else - reduce = Code.new(reduce) - end + reduce = Code.new(reduce) unless reduce.is_a?(Code) result = @db.command({"group" => { @@ -401,7 +406,7 @@ function () { return {"result": map.values()}; } EOS - return @db.eval(Code.new(group_function, scope))["result"] + @db.eval(Code.new(group_function, scope))["result"] end # Returns a list of distinct values for +key+ across all diff --git a/test/test_collection.rb b/test/test_collection.rb index 2e3ff44..d965fc8 100644 --- a/test/test_collection.rb +++ b/test/test_collection.rb @@ -271,10 +271,20 @@ class TestCollection < Test::Unit::TestCase m = "function() { emit(this.user_id, 1); }" r = "function(k,vals) { return 1; }" - res = @@test.mapreduce(m, r); + res = @@test.map_reduce(m, r); assert res.find_one({"_id" => 1}) assert res.find_one({"_id" => 2}) + end + def test_mapreduce_with_code_objects + @@test << { "user_id" => 1 } + @@test << { "user_id" => 2 } + + m = Code.new("function() { emit(this.user_id, 1); }") + r = Code.new("function(k,vals) { return 1; }") + res = @@test.map_reduce(m, r); + assert res.find_one({"_id" => 1}) + assert res.find_one({"_id" => 2}) end def test_saving_dates_pre_epoch