lib/thinking_sphinx/facet_search.rb in warp-thinking-sphinx-1.3.10 vs lib/thinking_sphinx/facet_search.rb in warp-thinking-sphinx-1.3.11

- old
+ new

@@ -1,136 +1,136 @@ module ThinkingSphinx class FacetSearch < Hash attr_accessor :args, :options - + def initialize(*args) ThinkingSphinx.context.define_indexes - + @options = args.extract_options! @args = args - + set_default_options - + populate end - + def for(hash = {}) for_options = {:with => {}}.merge(options) - + hash.each do |key, value| attrib = ThinkingSphinx::Facet.attribute_name_from_value(key, value) for_options[:with][attrib] = underlying_value key, value end - + ThinkingSphinx.search *(args + [for_options]) end - + def facet_names @facet_names ||= begin names = options[:all_facets] ? facet_names_for_all_classes : facet_names_common_to_all_classes - + names.delete "class_crc" unless options[:class_facet] names end end - + private - + def set_default_options options[:all_facets] ||= false if options[:class_facet].nil? options[:class_facet] = ((options[:classes] || []).length != 1) end end - + def populate facet_names.each do |name| search_options = facet_search_options.merge(:group_by => name) add_from_results name, ThinkingSphinx.search( *(args + [search_options]) ) end end - + def facet_search_options config = ThinkingSphinx::Configuration.instance max = config.configuration.searchd.max_matches || 1000 - + options.merge( :group_function => :attr, :limit => max, :max_matches => max, :page => 1 ) end - + def facet_classes ( options[:classes] || ThinkingSphinx.context.indexed_models.collect { |model| model.constantize } ).select { |klass| klass.sphinx_facets.any? } end - + def all_facets facet_classes.collect { |klass| klass.sphinx_facets }.flatten.select { |facet| options[:facets].blank? || Array(options[:facets]).include?(facet.name) } end - + def facet_names_for_all_classes all_facets.group_by { |facet| facet.name }.collect { |name, facets| if facets.collect { |facet| facet.type }.uniq.length > 1 raise "Facet #{name} exists in more than one model with different types" end facets.first.attribute_name } end - + def facet_names_common_to_all_classes facet_names_for_all_classes.select { |name| facet_classes.all? { |klass| klass.sphinx_facets.detect { |facet| facet.attribute_name == name } } } end - + def add_from_results(facet, results) name = ThinkingSphinx::Facet.name_for(facet) - + self[name] ||= {} - + return if results.empty? - + facet = facet_from_object(results.first, facet) if facet.is_a?(String) - + results.each_with_groupby_and_count { |result, group, count| facet_value = facet.value(result, group) - + self[name][facet_value] ||= 0 self[name][facet_value] += count } end - + def underlying_value(key, value) case value when Array value.collect { |item| underlying_value(key, item) } when String value.to_crc32 else value end end - + def facet_from_object(object, name) - object.sphinx_facets.detect { |facet| facet.attribute_name == name } + object.class.source_of_sphinx_index.sphinx_facets.detect { |facet| facet.attribute_name == name } end end end