diff --git a/lib/blacklight/configuration.rb b/lib/blacklight/configuration.rb index b9966c9948..75e2237074 100644 --- a/lib/blacklight/configuration.rb +++ b/lib/blacklight/configuration.rb @@ -78,6 +78,10 @@ def header_component # @since v5.2.0 # @return [String] The url path (relative to the solr base url) to use when requesting only a single document property :document_solr_path, default: 'get' + # @!attribute json_solr_path + # @since v7.34.0 + # @return [String] The url path (relative to the solr base url) to use when using Solr's JSON Query DSL (as with the advanced search) + property :json_solr_path, default: nil # @!attribute document_unique_id_param # @since v5.2.0 # @return [Symbol] The solr query parameter used for sending the unique identifiers for one or more documents diff --git a/lib/blacklight/solr/repository.rb b/lib/blacklight/solr/repository.rb index 8ff198c445..100075ae6e 100644 --- a/lib/blacklight/solr/repository.rb +++ b/lib/blacklight/solr/repository.rb @@ -20,7 +20,7 @@ def find id, params = {} # Execute a search query against solr # @param [Hash] params solr query parameters def search params = {} - send_and_receive blacklight_config.solr_path, params.reverse_merge(qt: blacklight_config.qt) + send_and_receive search_path(params), params.reverse_merge(qt: blacklight_config.qt) end # @param [Hash] request_params @@ -77,7 +77,7 @@ def send_and_receive(path, solr_params = {}) # @return [Hash] # @!visibility private def build_solr_request(solr_params) - if solr_params[:json].present? + if uses_json_query_dsl?(solr_params) { data: { params: solr_params.to_hash.except(:json) }.merge(solr_params[:json]).to_json, method: :post, @@ -121,5 +121,17 @@ def defined_rsolr_timeout_exceptions [] end end + + # @return [String] + def search_path(solr_params) + return blacklight_config.json_solr_path if blacklight_config.json_solr_path && uses_json_query_dsl?(solr_params) + + blacklight_config.solr_path + end + + # @return [Boolean] + def uses_json_query_dsl?(solr_params) + solr_params[:json].present? + end end end diff --git a/lib/generators/blacklight/templates/catalog_controller.rb b/lib/generators/blacklight/templates/catalog_controller.rb index 89cd1ecb65..7d27994715 100644 --- a/lib/generators/blacklight/templates/catalog_controller.rb +++ b/lib/generators/blacklight/templates/catalog_controller.rb @@ -29,6 +29,7 @@ class <%= controller_name.classify %>Controller < ApplicationController # solr path which will be added to solr base url before the other solr params. #config.solr_path = 'select' #config.document_solr_path = 'get' + #config.json_solr_path = 'advanced' # items to show per page, each number in the array represent another option to choose from. #config.per_page = [10,20,50,100] diff --git a/lib/generators/blacklight/templates/solr/conf/solrconfig.xml b/lib/generators/blacklight/templates/solr/conf/solrconfig.xml index c44ea70c1d..fe693e6c9c 100644 --- a/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +++ b/lib/generators/blacklight/templates/solr/conf/solrconfig.xml @@ -100,6 +100,75 @@ + + + + lucene + explicit + title_tsim + + id + full_title_tsim + short_title_tsim + alternative_title_tsim + active_fedora_model_ssi + title_tsim + author_tsim + subject_tsim + all_text_timv + + + all_text_timv^10 + + + + author_tsim + + + + + title_tsim + full_title_tsim + short_title_tsim + alternative_title_tsim + + + + + subject_tsim + + + + + + *, + score + + + true + 1 + 10 + active_fedora_model_ssi + subject_ssim + + true + default + true + true + false + 5 + + + + spellcheck + + + off diff --git a/spec/features/advanced_search_spec.rb b/spec/features/advanced_search_spec.rb index b49e704c62..eea7e96898 100644 --- a/spec/features/advanced_search_spec.rb +++ b/spec/features/advanced_search_spec.rb @@ -5,9 +5,28 @@ RSpec.describe "Blacklight Advanced Search Form" do describe "advanced search form" do before do + CatalogController.blacklight_config.search_fields['all_fields']['clause_params'] = { + edismax: {} + } + CatalogController.blacklight_config.search_fields['author']['clause_params'] = { + edismax: { qf: '${author_qf}' } + } + CatalogController.blacklight_config.search_fields['title']['clause_params'] = { + edismax: { qf: '${title_qf}' } + } + CatalogController.blacklight_config.search_fields['subject']['clause_params'] = { + edismax: { qf: '${subject_qf}' } + } + CatalogController.blacklight_config.json_solr_path = 'advanced' visit '/catalog/advanced?hypothetical_existing_param=true&q=ignore+this+existing+query' end + after do + %w[all_fields author title subject].each do |field| + CatalogController.blacklight_config.search_fields[field].delete(:clause_params) + end + end + it "has field and facet blocks" do expect(page).to have_selector('.query-criteria') expect(page).to have_selector('.limit-criteria') @@ -45,6 +64,43 @@ click_on 'advanced-search-submit' expect(page).to have_content 'Remove constraint Title: Medicine' expect(page).to have_content 'Strong Medicine speaks' + expect(page).to have_selector('article.document', count: 1) + end + + it 'can limit to facets' do + fill_in 'Subject', with: 'Women' + click_on 'Language' + check 'Urdu 3' + click_on 'advanced-search-submit' + expect(page).to have_content 'Pākistānī ʻaurat dorāhe par' + expect(page).not_to have_content 'Ajikto kŭrŏk chŏrŏk sasimnikka : and 아직도 그럭 저럭 사십니까' + expect(page).to have_selector('article.document', count: 1) + end + + it 'handles boolean queries' do + fill_in 'All Fields', with: 'history NOT strong' + click_on 'advanced-search-submit' + expect(page).to have_content('Ci an zhou bian') + expect(page).not_to have_content('Strong Medicine speaks') + expect(page).to have_selector('article.document', count: 10) + end + + it 'handles queries in multiple fields with the ALL operator' do + fill_in 'All Fields', with: 'history' + fill_in 'Author', with: 'hearth' + click_on 'advanced-search-submit' + expect(page).to have_content('Strong Medicine speaks') + expect(page).to have_selector('article.document', count: 1) + end + + it 'handles queries in multiple fields with the ANY operator' do + select 'any', from: 'op' + fill_in 'All Fields', with: 'history' + fill_in 'Subject', with: 'women' + click_on 'advanced-search-submit' + expect(page).to have_content('Ci an zhou bian') + expect(page).to have_content('Pākistānī ʻaurat dorāhe par') + expect(page).to have_selector('article.document', count: 10) end end diff --git a/spec/models/blacklight/solr/repository_spec.rb b/spec/models/blacklight/solr/repository_spec.rb index 751eea5bbc..17fbc08fa5 100644 --- a/spec/models/blacklight/solr/repository_spec.rb +++ b/spec/models/blacklight/solr/repository_spec.rb @@ -153,6 +153,33 @@ expect(JSON.parse(actual_params[:data]).with_indifferent_access).to include(query: { bool: {} }) expect(actual_params[:headers]).to include({ 'Content-Type' => 'application/json' }) end + + context "without a json solr path configured" do + before do + blacklight_config.json_solr_path = nil + end + + it "uses the default solr path" do + blacklight_config.solr_path = 'xyz' + allow(subject.connection).to receive(:send_and_receive) do |path| + expect(path).to eq 'xyz' + end + subject.search(input_params) + end + end + + context "with a json solr path configured" do + before do + blacklight_config.json_solr_path = 'my-great-json' + end + + it "uses the configured json_solr_path" do + allow(subject.connection).to receive(:send_and_receive) do |path| + expect(path).to eq 'my-great-json' + end + subject.search(input_params) + end + end end end