diff --git a/lib/mongo/collection.rb b/lib/mongo/collection.rb index a6a7854..740d624 100644 --- a/lib/mongo/collection.rb +++ b/lib/mongo/collection.rb @@ -470,6 +470,8 @@ module Mongo # @option opts [String] :out (nil) the name of the output collection. If specified, the collection will not be treated as temporary. # @option opts [Boolean] :keeptemp (false) if true, the generated collection will be persisted. default is false. # @option opts [Boolean ] :verbose (false) if true, provides statistics on job execution time. + # @options opts [Boolean] :raw (false) if true, return the raw result object from the map_reduce command, and not + # the instantiated collection that's returned by default. # # @return [Collection] a collection containing the results of the operation. # @@ -477,8 +479,10 @@ module Mongo # # @core mapreduce map_reduce-instance_method def map_reduce(map, reduce, opts={}) + opts.assert_valid_keys(:query, :sort, :limit, :finalize, :keeptemp, :verbose, :raw) map = BSON::Code.new(map) unless map.is_a?(BSON::Code) reduce = BSON::Code.new(reduce) unless reduce.is_a?(BSON::Code) + raw = opts.delete(:raw) hash = BSON::OrderedHash.new hash['mapreduce'] = self.name @@ -490,7 +494,12 @@ module Mongo unless Mongo::Support.ok?(result) raise Mongo::OperationFailure, "map-reduce failed: #{result['errmsg']}" end - @db[result["result"]] + + if raw + result + else + @db[result["result"]] + end end alias :mapreduce :map_reduce diff --git a/test/collection_test.rb b/test/collection_test.rb index 4fbde7b..43bb1f1 100644 --- a/test/collection_test.rb +++ b/test/collection_test.rb @@ -393,7 +393,7 @@ class TestCollection < Test::Unit::TestCase assert c.closed? end - if @@version < "1.1.1" + if @@version > "1.1.1" def test_map_reduce @@test << { "user_id" => 1 } @@test << { "user_id" => 2 } @@ -429,6 +429,23 @@ class TestCollection < Test::Unit::TestCase assert res.find_one({"_id" => 2}) assert res.find_one({"_id" => 3}) end + + def test_map_reduce_with_raw_response + m = Code.new("function() { emit(this.user_id, 1); }") + r = Code.new("function(k,vals) { return 1; }") + res = @@test.map_reduce(m, r, :raw => true) + assert res["result"] + assert res["counts"] + assert res["timeMillis"] + end + + def test_allows_only_valid_keys + m = Code.new("function() { emit(this.user_id, 1); }") + r = Code.new("function(k,vals) { return 1; }") + assert_raise ArgumentError do + @@test.map_reduce(m, r, :foo => true) + end + end end if @@version > "1.3.0"