Collection#group as eval deprecation final stage
This commit is contained in:
parent
25b783a0c8
commit
8f90cbfbf7
|
@ -415,100 +415,55 @@ module Mongo
|
||||||
# @param [String, Code] finalize :: optional. a JavaScript function that receives and modifies
|
# @param [String, Code] finalize :: optional. a JavaScript function that receives and modifies
|
||||||
# each of the resultant grouped objects. Available only when group is run
|
# each of the resultant grouped objects. Available only when group is run
|
||||||
# with command set to true.
|
# with command set to true.
|
||||||
# @param [Boolean] command if true, run the group as a command instead of in an
|
# @param [Nil] deprecated this param in a placeholder for a deprecated param. It will be removed
|
||||||
# eval. Note: Running group as eval has been DEPRECATED.
|
# in the next release.
|
||||||
#
|
#
|
||||||
# @return [Array] the grouped items.
|
# @return [Array] the grouped items.
|
||||||
def group(key, condition, initial, reduce, command=false, finalize=nil)
|
def group(key, condition, initial, reduce, finalize=nil, deprecated=nil)
|
||||||
|
|
||||||
if command
|
# Warn of changed API post eval deprecation.
|
||||||
|
if finalize == true || finalize == false || deprecated
|
||||||
|
warn "The API for Collection#group has changed. 'Finalize' is now the fifth parameter, " +
|
||||||
|
"since it's no longer necessary to specify whether #group is run as a command. " +
|
||||||
|
"See http://api.mongodb.org/ruby/current/Mongo/Collection.html#group-instance_method for details."
|
||||||
|
end
|
||||||
|
|
||||||
reduce = Code.new(reduce) unless reduce.is_a?(Code)
|
reduce = Code.new(reduce) unless reduce.is_a?(Code)
|
||||||
|
|
||||||
group_command = {
|
group_command = {
|
||||||
"group" => {
|
"group" => {
|
||||||
"ns" => @name,
|
"ns" => @name,
|
||||||
"$reduce" => reduce,
|
"$reduce" => reduce,
|
||||||
"cond" => condition,
|
"cond" => condition,
|
||||||
"initial" => initial
|
"initial" => initial
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unless key.nil?
|
unless key.nil?
|
||||||
if key.is_a? Array
|
if key.is_a? Array
|
||||||
key_type = "key"
|
key_type = "key"
|
||||||
key_value = {}
|
key_value = {}
|
||||||
key.each { |k| key_value[k] = 1 }
|
key.each { |k| key_value[k] = 1 }
|
||||||
else
|
|
||||||
key_type = "$keyf"
|
|
||||||
key_value = key.is_a?(Code) ? key : Code.new(key)
|
|
||||||
end
|
|
||||||
|
|
||||||
group_command["group"][key_type] = key_value
|
|
||||||
end
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
if result["ok"] == 1
|
|
||||||
return result["retval"]
|
|
||||||
else
|
else
|
||||||
raise OperationFailure, "group command failed: #{result['errmsg']}"
|
key_type = "$keyf"
|
||||||
|
key_value = key.is_a?(Code) ? key : Code.new(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
group_command["group"][key_type] = key_value
|
||||||
|
end
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
if result["ok"] == 1
|
||||||
|
result["retval"]
|
||||||
else
|
else
|
||||||
|
raise OperationFailure, "group command failed: #{result['errmsg']}"
|
||||||
warn "Collection#group must now be run as a command; you can do this by passing 'true' as the command argument."
|
|
||||||
|
|
||||||
raise OperationFailure, ":finalize can be specified only when " +
|
|
||||||
"group is run as a command (set command param to true)" if finalize
|
|
||||||
|
|
||||||
raise OperationFailure, "key must be an array of fields to group by. If you want to pass a key function,
|
|
||||||
run group as a command by passing 'true' as the command argument." unless key.is_a? Array || key.nil?
|
|
||||||
|
|
||||||
case reduce
|
|
||||||
when Code
|
|
||||||
scope = reduce.scope
|
|
||||||
else
|
|
||||||
scope = {}
|
|
||||||
end
|
|
||||||
scope.merge!({
|
|
||||||
"ns" => @name,
|
|
||||||
"keys" => key,
|
|
||||||
"condition" => condition,
|
|
||||||
"initial" => initial })
|
|
||||||
|
|
||||||
group_function = <<EOS
|
|
||||||
function () {
|
|
||||||
var c = db[ns].find(condition);
|
|
||||||
var map = new Map();
|
|
||||||
var reduce_function = #{reduce};
|
|
||||||
while (c.hasNext()) {
|
|
||||||
var obj = c.next();
|
|
||||||
|
|
||||||
var key = {};
|
|
||||||
for (var i = 0; i < keys.length; i++) {
|
|
||||||
var k = keys[i];
|
|
||||||
key[k] = obj[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
var aggObj = map.get(key);
|
|
||||||
if (aggObj == null) {
|
|
||||||
var newObj = Object.extend({}, key);
|
|
||||||
aggObj = Object.extend(newObj, initial);
|
|
||||||
map.put(key, aggObj);
|
|
||||||
}
|
|
||||||
reduce_function(obj, aggObj);
|
|
||||||
}
|
|
||||||
return {"result": map.values()};
|
|
||||||
}
|
|
||||||
EOS
|
|
||||||
@db.eval(Code.new(group_function, scope))["result"]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -437,15 +437,9 @@ class TestCollection < Test::Unit::TestCase
|
||||||
assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
|
assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
|
||||||
end
|
end
|
||||||
|
|
||||||
should "group results using command form" do
|
|
||||||
assert_equal 1, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 0.5}), true)[0]["count"]
|
|
||||||
assert_equal 2, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), true)[0]["count"]
|
|
||||||
assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}), true)[0]["count"]
|
|
||||||
end
|
|
||||||
|
|
||||||
should "finalize grouped results" do
|
should "finalize grouped results" do
|
||||||
@finalize = "function(doc) {doc.f = doc.count + 200; }"
|
@finalize = "function(doc) {doc.f = doc.count + 200; }"
|
||||||
assert_equal 202, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), true, @finalize)[0]["f"]
|
assert_equal 202, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), @finalize)[0]["f"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -463,16 +457,10 @@ class TestCollection < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
should "group results" do
|
should "group results" do
|
||||||
results = @@test.group(@keyf, {}, @initial, @reduce, true).sort {|a, b| a['count'] <=> b['count']}
|
results = @@test.group(@keyf, {}, @initial, @reduce).sort {|a, b| a['count'] <=> b['count']}
|
||||||
assert results[0]['even'] && results[0]['count'] == 2.0
|
assert results[0]['even'] && results[0]['count'] == 2.0
|
||||||
assert results[1]['odd'] && results[1]['count'] == 3.0
|
assert results[1]['odd'] && results[1]['count'] == 3.0
|
||||||
end
|
end
|
||||||
|
|
||||||
should "raise an error if trying to use keyf as a group eval" do
|
|
||||||
assert_raise OperationFailure do
|
|
||||||
@@test.group(@keyf, {}, @initial, @reduce)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "A collection with two records" do
|
context "A collection with two records" do
|
||||||
|
|
Loading…
Reference in New Issue