Add support for the finalize option of the group command

This commit is contained in:
Blythe Dunham 2009-12-06 15:45:42 -08:00
parent f7825eab82
commit 3df52cc927
3 changed files with 39 additions and 9 deletions

View File

@ -346,22 +346,34 @@ module Mongo
# :command :: if true, run the group as a command instead of in an # :command :: if true, run the group as a command instead of in an
# eval - it is likely that this option will eventually be # eval - it is likely that this option will eventually be
# deprecated and all groups will be run as commands # deprecated and all groups will be run as commands
def group(keys, condition, initial, reduce, command=false) def group(keys, condition, initial, reduce, command=false, finalize=nil)
if command if command
hash = {} hash = {}
keys.each do |k| keys.each do |k|
hash[k] = 1 hash[k] = 1
end end
reduce = Code.new(reduce) unless reduce.is_a?(Code) reduce = Code.new(reduce) unless reduce.is_a?(Code)
group_command = {
"group" => {
"ns" => @name,
"$reduce" => reduce,
"key" => hash,
"cond" => condition,
"initial" => initial
}
}
# only add finalize if specified
if finalize
finalize = Code.new(finalize) unless finalize.is_a?(Code)
group_command['group']['finalize'] = finalize
end
result = @db.command group_command
result = @db.command({"group" =>
{
"ns" => @name,
"$reduce" => reduce,
"key" => hash,
"cond" => condition,
"initial" => initial}})
if result["ok"] == 1 if result["ok"] == 1
return result["retval"] return result["retval"]
else else
@ -369,6 +381,8 @@ module Mongo
end end
end end
raise OperationFailure, "finalize is only supported with the group command" if finalize
case reduce case reduce
when Code when Code
scope = reduce.scope scope = reduce.scope

View File

@ -377,6 +377,16 @@ class TestCollection < Test::Unit::TestCase
# assert_equal 1, @@test.group([], {}, {"count" => 0}, # assert_equal 1, @@test.group([], {}, {"count" => 0},
# Code.new(reduce_function, # Code.new(reduce_function,
# {"inc_value" => 0.5}), true)[0]["count"] # {"inc_value" => 0.5}), true)[0]["count"]
# test finalize
#assert_equal( 3,
# @@test.group(
# [], {}, {"count" => 0},
# Code.new(reduce_function,{"inc_value" => 2}), true,
# Code.new("function (o) { o.final_count = o.count - 1; }")
# )[0]["final_count"]
#)
end end
context "A collection with two records" do context "A collection with two records" do

View File

@ -553,6 +553,12 @@ class DBAPITest < Test::Unit::TestCase
assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"] assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true)[0]["count"] assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true)[0]["count"]
finalize = "function (obj) { obj.f = obj.count - 1; }"
assert_equal 2, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true, finalize)[0]["f"]
assert_raise OperationFailure do
test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }", false, finalize)[0]["f"]
end
test.insert("a" => 2, "b" => 3) test.insert("a" => 2, "b" => 3)
expected = [{"a" => 2, "count" => 2}, expected = [{"a" => 2, "count" => 2},
{"a" => nil, "count" => 1}, {"a" => nil, "count" => 1},