YUKI Hiroshi
null+****@clear*****
Wed Dec 4 19:22:11 JST 2013
YUKI Hiroshi 2013-12-04 19:22:11 +0900 (Wed, 04 Dec 2013) New Revision: be54d1e24043ea551e138c35aecfe103e9f5f434 https://github.com/droonga/fluent-plugin-droonga/commit/be54d1e24043ea551e138c35aecfe103e9f5f434 Message: Calculate count of grouped results correctly Modified files: lib/droonga/plugin/collector/basic.rb lib/droonga/plugin/distributor/search.rb Modified: lib/droonga/plugin/collector/basic.rb (+19 -2) =================================================================== --- lib/droonga/plugin/collector/basic.rb 2013-12-04 19:01:26 +0900 (149c6a6) +++ lib/droonga/plugin/collector/basic.rb 2013-12-04 19:22:11 +0900 (b50646e) @@ -29,11 +29,28 @@ module Droonga if output.is_a?(Hash) elements = output["elements"] if elements && elements.is_a?(Hash) + # phase 1: pre-process elements.each do |element, mapper| case mapper["type"] + when "count" + result[element] = result[mapper["target"]].size + mapper["drop_elements"].each do |drop_element| + result.delete(drop_element) + end when "sort" - result[element] = apply_output_range(result[element], mapper) - result[element] = apply_output_attributes_and_format(result[element], mapper) + end + end + # phase 2: post-process + elements.each do |element, mapper| + case mapper["type"] + when "count" + when "sort" + # because "count" type mapper requres all items of the array, + # I have to apply "sort" type mapper later. + if result[element] + result[element] = apply_output_range(result[element], mapper) + result[element] = apply_output_attributes_and_format(result[element], mapper) + end end end end Modified: lib/droonga/plugin/distributor/search.rb (+27 -13) =================================================================== --- lib/droonga/plugin/distributor/search.rb 2013-12-04 19:01:26 +0900 (153df1f) +++ lib/droonga/plugin/distributor/search.rb 2013-12-04 19:22:11 +0900 (bd652bc) @@ -59,16 +59,31 @@ module Droonga final_offset, final_limit = calculate_offset_and_limit!(query) elements = {} - output["elements"].each do |element| - case element - when "count" - elements[element] = { + + if output["elements"].include?("count") + elements["count"] = { "type" => "sum", } - when "records" - # Skip reducing phase for a result with no record output. - next if final_limit.zero? + if output["unifiable"] + if query["sortBy"] && query["sortBy"].is_a?(Hash) + query["sortBy"]["limit"] = -1 + end + output["limit"] = -1 + mapper = { + "type" => "count", + "target" => "records", + } + unless output["elements"].include?("records") + output["elements"] << "records" + output["attributes"] ||= ["_key"] + mapper["drop_elements"] = ["records"] + end + output_mapper[output_name]["elements"]["count"] = mapper + end + end + # Skip reducing phase for a result with no record output. + if output["elements"].include?("records") && !final_limit.zero? # Append sort key attributes to the list of output attributes # temporarily, for the reducing phase. After all extra columns # are removed on the gathering phase. @@ -80,23 +95,22 @@ module Droonga output["attributes"] << "_key" end - elements[element] = sort_reducer(:attributes => output["attributes"], - :sort_keys => query["sortBy"], - :unifiable => unifiable) + elements["records"] = sort_reducer(:attributes => output["attributes"], + :sort_keys => query["sortBy"], + :unifiable => unifiable) # On the reducing phase, we apply only "limit". We cannot apply # "offset" on this phase because the collecter merges a pair of # results step by step even if there are three or more results. # Instead, we apply "offset" on the gethering phase. - elements[element]["limit"] = output["limit"] + elements["records"]["limit"] = output["limit"] - output_mapper[output_name]["elements"][element] = { + output_mapper[output_name]["elements"]["records"] = { "type" => "sort", "offset" => final_offset, "limit" => final_limit, "format" => final_format, "attributes" => final_attributes, } - end end reducer = { -------------- next part -------------- HTML����������������������������... 下载