From 29aff189f4989f51ac59695d978f012c57122909 Mon Sep 17 00:00:00 2001 From: apple Date: Fri, 12 Jan 2024 21:02:41 -0500 Subject: [PATCH] Use lucene query parser for search within user-created browse categories --- .../browse_category_search_builder.rb | 11 ++- .../browse_category_search_builder_spec.rb | 71 +++++++++++++------ 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/app/models/concerns/spotlight/browse_category_search_builder.rb b/app/models/concerns/spotlight/browse_category_search_builder.rb index c1fe41fc3..bcb30dc8c 100644 --- a/app/models/concerns/spotlight/browse_category_search_builder.rb +++ b/app/models/concerns/spotlight/browse_category_search_builder.rb @@ -31,12 +31,21 @@ def fix_up_browse_category_queries(solr_params) solr_params.append_query(query) if query.present? + # for a browse category formed from a saved search, the query syntax reads as two "must" values + # e.g. "json"=>{"query"=>{"bool"=>{"must"=>["savedsearchterm", "browsecategorysearchterm"]}}}} + must_values = solr_params.dig(:json, :query, :bool, :must) + + return unless must_values&.any? + + # this type of query must be parsed by lucene to function + solr_params[:defType] = 'lucene' + # This replicates existing spotlight 2.x search behavior, more or less. It # doesn't take into account the possibility that the browse category query # could use a different search field (which.. doesn't have an existing UI # control.. and may require additional upstream work to properly encapsulate # the two query parameters) - solr_params.dig(:json, :query, :bool, :must)&.map! do |q| + must_values.map! do |q| q.is_a?(String) ? { edismax: { query: q } } : q end end diff --git a/spec/models/spotlight/browse_category_search_builder_spec.rb b/spec/models/spotlight/browse_category_search_builder_spec.rb index fda7d9662..ab14111f2 100644 --- a/spec/models/spotlight/browse_category_search_builder_spec.rb +++ b/spec/models/spotlight/browse_category_search_builder_spec.rb @@ -14,37 +14,64 @@ class BrowseCategoryMockSearchBuilder < Blacklight::SearchBuilder end let(:solr_request) { Blacklight::Solr::Request.new } let(:blacklight_params) { { browse_category_id: search.id } } - let(:search) { FactoryBot.create(:search, exhibit: exhibit, query_params: { sort: 'type', f: { genre_ssim: ['term'] }, q: 'search query' }) } - describe '#restrict_to_browse_category' do - it 'adds the search query parameters from the browse category' do - params = subject.to_hash.with_indifferent_access + context 'with a facet as the basis of the browse category (no search query present)' do + let(:search) { FactoryBot.create(:search, exhibit: exhibit, query_params: { sort: 'type', f: { genre_ssim: ['genre facet'] } }) } - expect(params).to include( - q: 'search query', - fq: ['{!term f=genre_ssim}term'], - sort: 'sort_type_ssi asc' - ) + describe 'constructs params properly' do + it 'adds facet to the solr params' do + params = subject.to_hash.with_indifferent_access + + expect(params).to include( + fq: ['{!term f=genre_ssim}genre facet'], + sort: 'sort_type_ssi asc' + ) + end + + it 'does not override the default query parser' do + params = subject.to_hash.with_indifferent_access + expect(params).not_to include(:defType) + end end + end - context 'with a user-provided query' do - let(:blacklight_params) { { browse_category_id: search.id, q: 'cats' } } + context 'with a search query as part of the construction of the browse category' do + let(:search) { FactoryBot.create(:search, exhibit: exhibit, query_params: { sort: 'type', f: { genre_ssim: ['term'] }, q: 'search query' }) } - it 'uses the user-provided query to further restrict the search' do + describe 'constructs params properly' do + it 'includes the facet and the seach term information in the params' do params = subject.to_hash.with_indifferent_access - expect(params).not_to include(:q) + expect(params).to include( - json: { - query: { - bool: { - must: [ - { edismax: { query: 'search query' } }, - { edismax: { query: 'cats' } } - ] + q: 'search query', + fq: ['{!term f=genre_ssim}term'], + sort: 'sort_type_ssi asc' + ) + end + + context 'with a search term present' do + let(:blacklight_params) { { browse_category_id: search.id, q: 'cats' } } + + it 'manipulates the solr query as expected into json syntax' do + params = subject.to_hash.with_indifferent_access + expect(params).not_to include(:q) + expect(params).to include( + json: { + query: { + bool: { + must: [ + { edismax: { query: 'search query' } }, + { edismax: { query: 'cats' } } + ] + } } } - } - ) + ) + end + + it 'overrides the default query parser' do + expect(params).to include(defType: 'lucene') + end end end end