module Scrivito class ObjSearchEnumerator # # Response format (assuming we've requested facets for attributes "color" and "size"): # # [ # # Facets for attribute "color" # [ # {value: "red", total: 2, results: [{id: "xxx"}, {id: "yyy"}]}, # {value: "blue", total: 1, results: [{id: "xxx"}]}, # {value: "green", total: 0, results: []}, # ], # # # Facets for attribute "size" # [ # {value: "large", total: 2, results: [{id: "xxx"}, {id: "yyy"}]}, # {value: "medium", total: 1, results: [{id: "xxx"}]}, # {value: "small", total: 0, results: []}, # ] # ] # # class FacetQuery < Struct.new(:facet_params, :search_params, :workspace) attr_reader :batch, :result def execute! @result = case when facet_params.first.empty? {} when facet_params.one? && facet_params.first.is_a?(Hash) fetch_result(multi_facet_params, facet_params.first.keys) else attribute_name = facet_params.first fetch_result([single_facet_params(*facet_params)], [attribute_name])[attribute_name] end end private def fetch_result(params, attribute_names) result = attribute_names.each_with_object({}) { |v, h| h[v] = [] } @batch = Scrivito::ObjSearchEnumerator::QueryExecutor.new(workspace).call( build_search_params(params)) objs = workspace.objs.find(obj_ids_from_batch) @batch.facets.each_with_index do |facets_per_attribute, i| result[result.keys[i]] += obj_facet_values(facets_per_attribute, objs) end result end def obj_ids_from_batch ids = [] @batch.facets.each do |facets_per_attribute| facets_per_attribute.each do |facet_hash| ids += obj_ids_from_facet_hash(facet_hash) end end ids end def multi_facet_params facet_params.first.map do |attribute_name, options| single_facet_params(attribute_name, options) end end def single_facet_params(attribute, options = {}) {attribute: attribute}.merge!(options) end def obj_facet_values(facets_per_attribute, objs) results = [] facets_per_attribute.map do |facet_hash| obj_ids = obj_ids_from_facet_hash(facet_hash) included_objs = [] objs.each do |obj| if obj_ids.include?(obj.id) && !included_objs.include?(obj) included_objs << obj end end results << Scrivito::ObjFacetValue.new( facet_hash['value'], facet_hash['total'], included_objs) end results end def obj_ids_from_facet_hash(facet_hash) facet_hash['results'].map { |obj_hash| obj_hash['id'] } end def build_search_params(params) params = {facets: params} params.merge!(search_params) if search_params params.reverse_merge(size: 0) end end end end