class Blacklight::SearchBuilder
Blacklight’s SearchBuilder
converts blacklight request parameters into query parameters appropriate for search index. It does so by evaluating a chain of processing methods to populate a result hash (see {#to_hash}).
Attributes
Public Class Methods
@overload initialize(scope)
@param [Object] scope scope the scope where the filter methods reside in.
@overload initialize(processor_chain
, scope)
@param [List<Symbol>,TrueClass] processor_chain options a list of filter methods to run or true, to use the default methods @param [Object] scope the scope where the filter methods reside in.
# File lib/blacklight/search_builder.rb, line 19 def initialize(*options) case options.size when 1 @processor_chain = default_processor_chain.dup @scope = options.first when 2 @processor_chain, @scope = options else raise ArgumentError, "wrong number of arguments. (#{options.size} for 1..2)" end @blacklight_params = {} search_state_class = @scope.try(:search_state_class) || Blacklight::SearchState @search_state = search_state_class.new(@blacklight_params, @scope&.blacklight_config, @scope) @additional_filters = {} @merged_params = {} @reverse_merged_params = {} end
Public Instance Methods
Append additional processor chain directives
# File lib/blacklight/search_builder.rb, line 62 def append(*addl_processor_chain) params_will_change! builder = self.class.new(processor_chain + addl_processor_chain, scope) .with(search_state) .merge(@merged_params) .reverse_merge(@reverse_merged_params) builder.start = @start if @start builder.rows = @rows if @rows builder.page = @page if @page builder.facet = @facet if @facet builder end
Converse to append, remove processor chain directives, returning a new builder that’s a copy of receiver with specified change.
Methods in argument that aren’t currently in processor chain are ignored as no-ops, rather than raising.
# File lib/blacklight/search_builder.rb, line 83 def except(*except_processor_chain) builder = self.class.new(processor_chain - except_processor_chain, scope) .with(search_state) .merge(@merged_params) .reverse_merge(@reverse_merged_params) builder.start = @start if @start builder.rows = @rows if @rows builder.page = @page if @page builder.facet = @facet if @facet builder end
@param [Object] value
# File lib/blacklight/search_builder.rb, line 219 def facet(value = nil) if value self.facet = value return self end @facet end
sets the facet that this query pertains to, for the purpose of facet pagination
# File lib/blacklight/search_builder.rb, line 213 def facet=(value) params_will_change! @facet = value end
Merge additional, repository-specific parameters
# File lib/blacklight/search_builder.rb, line 98 def merge(extra_params, &block) if extra_params params_will_change! @merged_params.merge!(extra_params.to_hash, &block) end self end
@param [#to_i] value
# File lib/blacklight/search_builder.rb, line 183 def page(value = nil) if value self.page = value return self end @page ||= search_state.page end
# File lib/blacklight/search_builder.rb, line 176 def page=(value) params_will_change! @page = value.to_i @page = 1 if @page < 1 end
The CatalogController index action uses this. Solr
parameters can come from a number of places. From lowest precedence to highest:
1. General defaults in blacklight config (are trumped by) 2. defaults for the particular search field identified by params[:search_field] (are trumped by) 3. certain parameters directly on input HTTP query params * not just any parameter is grabbed willy nilly, only certain ones are allowed by HTTP input) * for legacy reasons, qt in http query does not over-ride qt in search field definition default. 4. extra parameters passed in as argument.
spellcheck.q will be supplied with the [:q] value unless specifically specified otherwise.
Incoming parameter :f is mapped to :fq solr parameter.
@return a params hash for searching solr.
# File lib/blacklight/search_builder.rb, line 148 def processed_parameters request.tap do |request_parameters| processor_chain.each do |method_name| send(method_name, request_parameters) end end end
“Reverse merge” additional, repository-specific parameters
# File lib/blacklight/search_builder.rb, line 108 def reverse_merge(extra_params, &block) if extra_params params_will_change! @reverse_merged_params.reverse_merge!(extra_params.to_hash, &block) end self end
@param [#to_i] value
# File lib/blacklight/search_builder.rb, line 197 def rows(value = nil) if value self.rows = value return self end @rows ||= begin # user-provided parameters should override any default row r = search_state.per_page # ensure we don't excede the max page size r.nil? ? nil : [r, blacklight_config.max_per_page].map(&:to_i).min end end
# File lib/blacklight/search_builder.rb, line 191 def rows=(value) params_will_change! @rows = [value, blacklight_config.max_per_page].map(&:to_i).min end
Decode the user provided ‘sort’ parameter into a sort string that can be passed to the search. This sanitizes the input by ensuring only configured search values are passed through to the search. @return [String] the field/fields to sort by
# File lib/blacklight/search_builder.rb, line 231 def sort search_state.sort_field&.sort end
@param [#to_i] value
# File lib/blacklight/search_builder.rb, line 164 def start(value = nil) if value self.start = value return self end @start ||= (page - 1) * (rows || 10) val = @start || 0 val = 0 if @start < 0 val end
# File lib/blacklight/search_builder.rb, line 158 def start=(value) params_will_change! @start = value.to_i end
a solr query method @return [Blacklight::Solr::Response] the solr response object
# File lib/blacklight/search_builder.rb, line 120 def to_hash return @params unless params_need_update? @params = processed_parameters .reverse_merge(@reverse_merged_params) .merge(@merged_params) .tap { clear_changes } end
Update the :q (query) parameter @param [Hash<Symbol,Object>] conditions the field and values to query on @example
search_builder.where(id: [1,2,3]) # produces: q:"{!lucene}id:(1 OR 2 OR 3)"
# File lib/blacklight/search_builder.rb, line 52 def where(conditions) params_will_change! @search_state = @search_state.reset(@search_state.params.merge(q: conditions)) @blacklight_params = @search_state.params @additional_filters = conditions self end
Set the parameters to pass through the processor chain
# File lib/blacklight/search_builder.rb, line 40 def with(blacklight_params_or_search_state = {}) params_will_change! @search_state = blacklight_params_or_search_state.is_a?(Blacklight::SearchState) ? blacklight_params_or_search_state : @search_state.reset(blacklight_params_or_search_state) @blacklight_params = @search_state.params.dup self end
Private Instance Methods
# File lib/blacklight/search_builder.rb, line 261 def clear_changes @dirty = false end
# File lib/blacklight/search_builder.rb, line 253 def params_changed? !!@dirty end
# File lib/blacklight/search_builder.rb, line 257 def params_need_update? params_changed? || @params.nil? end
# File lib/blacklight/search_builder.rb, line 249 def params_will_change! @dirty = true end
# File lib/blacklight/search_builder.rb, line 239 def request Blacklight::Solr::Request.new end
# File lib/blacklight/search_builder.rb, line 243 def should_add_field_to_request? _field_name, field field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request) end