From d7162d72f357865f5e33d2c0400896b177cf4672 Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Mon, 1 Dec 2014 17:35:22 -0800 Subject: [PATCH] Move solr request parameter building into the RequestBuilders module --- lib/blacklight/request_builders.rb | 92 +++++++++++++++++++++++++++- lib/blacklight/solr_helper.rb | 96 +++--------------------------- lib/blacklight/solr_repository.rb | 2 +- 3 files changed, 100 insertions(+), 90 deletions(-) diff --git a/lib/blacklight/request_builders.rb b/lib/blacklight/request_builders.rb index 7dd0ae998..72402bd81 100644 --- a/lib/blacklight/request_builders.rb +++ b/lib/blacklight/request_builders.rb @@ -21,7 +21,7 @@ module RequestBuilders # CatalogController.include ModuleDefiningNewMethod # CatalogController.solr_search_params_logic += [:new_method] # CatalogController.solr_search_params_logic.delete(:we_dont_want) - self.solr_search_params_logic = [:default_solr_parameters , :add_query_to_solr, :add_facet_fq_to_solr, :add_facetting_to_solr, :add_solr_fields_to_query, :add_paging_to_solr, :add_sorting_to_solr, :add_group_config_to_solr ] + self.solr_search_params_logic = [:default_solr_parameters, :add_query_to_solr, :add_facet_fq_to_solr, :add_facetting_to_solr, :add_solr_fields_to_query, :add_paging_to_solr, :add_sorting_to_solr, :add_group_config_to_solr ] if self.respond_to?(:helper_method) helper_method(:facet_limit_for) @@ -51,6 +51,78 @@ def solr_search_params(user_params = params || {}) end end + def solr_response_for_document_ids(ids = []) + q = if Array(ids).empty? + "{!lucene}NOT *:*" + else + "{!lucene}#{blacklight_config.solr_document_model.unique_key}:(#{ Array(ids).map { |x| solr_param_quote(x) }.join(" OR ")})" + end + + { q: q, spellcheck: 'false', fl: "*" } + end + + # returns a params hash for a single facet field solr query. + # used primary by the get_facet_pagination method. + # Looks up Facet Paginator request params from current request + # params to figure out sort and offset. + # Default limit for facet list can be specified by defining a controller + # method facet_list_limit, otherwise 20. + def solr_facet_params(facet_field, user_params=params || {}, extra_controller_params={}) + input = user_params.deep_merge(extra_controller_params) + facet_config = blacklight_config.facet_fields[facet_field] + + solr_params = {} + + # Now override with our specific things for fetching facet values + solr_params[:"facet.field"] = with_ex_local_param((facet_config.ex if facet_config.respond_to?(:ex)), facet_field) + + limit = + if respond_to?(:facet_list_limit) + facet_list_limit.to_s.to_i + elsif solr_params["facet.limit"] + solr_params["facet.limit"].to_i + else + 20 + end + + # Need to set as f.facet_field.facet.* to make sure we + # override any field-specific default in the solr request handler. + solr_params[:"f.#{facet_field}.facet.limit"] = limit + 1 + solr_params[:"f.#{facet_field}.facet.offset"] = ( input.fetch(Blacklight::Solr::FacetPaginator.request_keys[:page] , 1).to_i - 1 ) * ( limit ) + solr_params[:"f.#{facet_field}.facet.sort"] = input[ Blacklight::Solr::FacetPaginator.request_keys[:sort] ] if input[ Blacklight::Solr::FacetPaginator.request_keys[:sort] ] + solr_params[:rows] = 0 + + solr_params + end + + # returns a solr params hash + # the :fl (solr param) is set to the "field" value. + # per_page is set to 10 + def solr_opensearch_params(field) + solr_params = {} + solr_params[:per_page] = 10 + solr_params[:fl] = field + solr_params + end + + def previous_and_next_document_params(index) + + solr_params = {} + + if index > 0 + solr_params[:start] = index - 1 # get one before + solr_params[:rows] = 3 # and one after + else + solr_params[:start] = 0 # there is no previous doc + solr_params[:rows] = 2 # but there should be one after + end + + solr_params[:fl] = '*' + solr_params[:facet] = false + solr_params + end + + #### # Start with general defaults from BL config. Need to use custom # merge to dup values, to avoid later mutating the original by mistake. @@ -286,8 +358,26 @@ def facet_limit_for(facet_field) end + # A helper method used for generating solr LocalParams, put quotes + # around the term unless it's a bare-word. Escape internal quotes + # if needed. + def solr_param_quote(val, options = {}) + options[:quote] ||= '"' + unless val =~ /^[a-zA-Z0-9$_\-\^]+$/ + val = options[:quote] + + # Yes, we need crazy escaping here, to deal with regexp esc too! + val.gsub("'", "\\\\\'").gsub('"', "\\\\\"") + + options[:quote] + end + return val + end + private + def should_add_to_solr field_name, field + field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request) + end + ## # Convert a facet/value pair into a solr fq parameter def facet_value_to_fq_string(facet_field, value) diff --git a/lib/blacklight/solr_helper.rb b/lib/blacklight/solr_helper.rb index d1d12525d..61a7b2b7f 100644 --- a/lib/blacklight/solr_helper.rb +++ b/lib/blacklight/solr_helper.rb @@ -73,7 +73,7 @@ def get_search_results(user_params = params || {}, extra_controller_params = {}) # given a user query, # @return [Blacklight::SolrResponse] the solr response object def query_solr(user_params = params || {}, extra_controller_params = {}) - solr_params = {qt: blacklight_config.qt}.merge(self.solr_search_params(user_params).merge(extra_controller_params)) + solr_params = self.solr_search_params(user_params).merge(extra_controller_params) solr_repository.search(solr_params) end @@ -87,51 +87,11 @@ def get_solr_response_for_doc_id(id=nil, extra_controller_params={}) end def get_solr_response_for_document_ids(ids=[], user_params = params || {}, extra_controller_params = {}) - q = if Array(ids).empty? - "{!lucene}NOT *:*" - else - "{!lucene}#{blacklight_config.solr_document_model.unique_key}:(#{ Array(ids).map { |x| solr_param_quote(x) }.join(" OR ")})" - end - - solr_response = query_solr(user_params, extra_controller_params.merge(q: q, spellcheck: 'false', fl: "*")) + solr_response = query_solr(user_params, extra_controller_params.merge(solr_response_for_document_ids(ids))) [solr_response, solr_response.documents] end - # returns a params hash for a single facet field solr query. - # used primary by the get_facet_pagination method. - # Looks up Facet Paginator request params from current request - # params to figure out sort and offset. - # Default limit for facet list can be specified by defining a controller - # method facet_list_limit, otherwise 20. - def solr_facet_params(facet_field, user_params=params || {}, extra_controller_params={}) - input = user_params.deep_merge(extra_controller_params) - facet_config = blacklight_config.facet_fields[facet_field] - - solr_params = {} - - # Now override with our specific things for fetching facet values - solr_params[:"facet.field"] = with_ex_local_param((facet_config.ex if facet_config.respond_to?(:ex)), facet_field) - - limit = - if respond_to?(:facet_list_limit) - facet_list_limit.to_s.to_i - elsif solr_params["facet.limit"] - solr_params["facet.limit"].to_i - else - 20 - end - - # Need to set as f.facet_field.facet.* to make sure we - # override any field-specific default in the solr request handler. - solr_params[:"f.#{facet_field}.facet.limit"] = limit + 1 - solr_params[:"f.#{facet_field}.facet.offset"] = ( input.fetch(Blacklight::Solr::FacetPaginator.request_keys[:page] , 1).to_i - 1 ) * ( limit ) - solr_params[:"f.#{facet_field}.facet.sort"] = input[ Blacklight::Solr::FacetPaginator.request_keys[:sort] ] if input[ Blacklight::Solr::FacetPaginator.request_keys[:sort] ] - solr_params[:rows] = 0 - - return solr_params - end - ## # Get the solr response when retrieving only a single facet field # @return [Blacklight::SolrResponse] the solr response @@ -144,19 +104,7 @@ def get_facet_field_response(facet_field, user_params = params || {}, extra_cont # @return [Blacklight::SolrResponse, Array] the solr response and a list of the first and last document def get_previous_and_next_documents_for_search(index, request_params, extra_controller_params={}) - solr_params = {} - - if index > 0 - solr_params[:start] = index - 1 # get one before - solr_params[:rows] = 3 # and one after - else - solr_params[:start] = 0 # there is no previous doc - solr_params[:rows] = 2 # but there should be one after - end - - solr_params[:fl] = '*' - solr_params[:facet] = false - solr_response = query_solr(request_params, extra_controller_params.merge(solr_params)) + solr_response = query_solr(request_params, extra_controller_params.merge(previous_and_next_document_params(index))) document_list = solr_response.documents @@ -166,16 +114,6 @@ def get_previous_and_next_documents_for_search(index, request_params, extra_cont [solr_response, [prev_doc, next_doc]] end - - # returns a solr params hash - # the :fl (solr param) is set to the "field" value. - # per_page is set to 10 - def solr_opensearch_params(field=nil) - solr_params = {} - solr_params[:per_page] = 10 - solr_params[:fl] = field || blacklight_config.view_config('opensearch').title_field - solr_params - end # a solr query method # does a standard search but returns a simplified object. @@ -184,9 +122,11 @@ def solr_opensearch_params(field=nil) # all of the field values for each of the documents... # where the field is the "field" argument passed in. def get_opensearch_response(field=nil, request_params = params || {}, extra_controller_params={}) - response = query_solr(request_params, solr_opensearch_params().merge(extra_controller_params)) - a = [request_params[:q]] - a << response.documents.map {|doc| doc[request_params[:fl]].to_s } + field ||= blacklight_config.view_config('opensearch').title_field + + response = query_solr(request_params, solr_opensearch_params(field).merge(extra_controller_params)) + + [response.params[:q], response.documents.flat_map {|doc| doc[field] }.uniq] end ## @@ -199,24 +139,4 @@ def solr_repository @solr_repository ||= Blacklight::SolrRepository.new(blacklight_config) end - # A helper method used for generating solr LocalParams, put quotes - # around the term unless it's a bare-word. Escape internal quotes - # if needed. - def solr_param_quote(val, options = {}) - options[:quote] ||= '"' - unless val =~ /^[a-zA-Z0-9$_\-\^]+$/ - val = options[:quote] + - # Yes, we need crazy escaping here, to deal with regexp esc too! - val.gsub("'", "\\\\\'").gsub('"', "\\\\\"") + - options[:quote] - end - return val - end - - private - - def should_add_to_solr field_name, field - field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request) - end - end diff --git a/lib/blacklight/solr_repository.rb b/lib/blacklight/solr_repository.rb index 3d91710eb..37698470b 100644 --- a/lib/blacklight/solr_repository.rb +++ b/lib/blacklight/solr_repository.rb @@ -18,7 +18,7 @@ def find id, params = {} end def search params = {} - send_and_receive blacklight_config.solr_path, params + send_and_receive blacklight_config.solr_path, { qt: blacklight_config.qt }.merge(params) end protected