Module: Blacklight::Solr::SearchBuilderBehavior
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/blacklight/solr/search_builder_behavior.rb
Instance Method Summary collapse
- #add_additional_filters(solr_parameters, additional_filters = nil) ⇒ Object
-
#add_adv_search_clauses(solr_parameters) ⇒ Object
Transform “clause” parameters into the Solr JSON Query DSL.
-
#add_facet_fq_to_solr(solr_parameters) ⇒ Object
Add any existing facet limits, stored in app-level HTTP query as :f, to solr as appropriate :fq query.
- #add_facet_paging_to_solr(solr_params) ⇒ Object
-
#add_facetting_to_solr(solr_parameters) ⇒ Object
Add appropriate Solr facetting directives in, including taking account of our facet paging/'more'.
-
#add_group_config_to_solr(solr_parameters) ⇒ Object
Remove the group parameter if we've faceted on the group field (e.g. for the full results for a group).
-
#add_paging_to_solr(solr_params) ⇒ Object
copy paging params from BL app over to solr, changing app level per_page and page to Solr rows and start.
-
#add_query_to_solr(solr_parameters) ⇒ Object
Take the user-entered query, and put it in the solr params, including config's “search field” params for current search field.
- #add_search_field_default_parameters(solr_parameters) ⇒ Object
- #add_search_field_with_json_query_parameters(solr_parameters) ⇒ Object
- #add_solr_facet_json_params(solr_parameters, field_name, facet, **additional_parameters) ⇒ Object
- #add_solr_fields_to_query(solr_parameters) ⇒ Object
-
#add_sorting_to_solr(solr_parameters) ⇒ Object
copy sorting params from BL app over to solr.
-
#adv_search_clause(clause, default_op) ⇒ Array
The first element is the query operator and the second is the value to add.
-
#default_solr_parameters(solr_parameters) ⇒ Object
Start with general defaults from BL config.
-
#facet_limit_for(facet_field) ⇒ Object
Look up facet limit for given facet_field.
-
#facet_limit_with_pagination(field_name) ⇒ Object
Support facet paging and 'more' links, by sending a facet.limit one more than what we want to page at, according to configured facet limits.
-
#solr_param_quote(val, options = {}) ⇒ Object
A helper method used for generating solr LocalParams, put quotes around the term unless it's a bare-word.
- #with_ex_local_param(ex, value) ⇒ Object
Instance Method Details
#add_additional_filters(solr_parameters, additional_filters = nil) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 84 def add_additional_filters(solr_parameters, additional_filters = nil) q = additional_filters || @additional_filters return if q.blank? if q.values.any?(&:blank?) # if any field parameters are empty, exclude _all_ results solr_parameters.append_query "{!lucene}NOT *:*" else composed_query = q.map do |field, values| "#{field}:(#{Array(values).map { |x| solr_param_quote(x) }.join(' OR ')})" end.join(" AND ") solr_parameters.append_query "{!lucene}#{composed_query}" end solr_parameters[:defType] = 'lucene' solr_parameters[:spellcheck] = 'false' end |
#add_adv_search_clauses(solr_parameters) ⇒ Object
Transform “clause” parameters into the Solr JSON Query DSL
111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 111 def add_adv_search_clauses(solr_parameters) return if search_state.clause_params.blank? defaults = { must: [], must_not: [], should: [] } default_op = blacklight_params[:op]&.to_sym || :must solr_parameters[:mm] = 1 if default_op == :should && search_state.clause_params.values.any? { |clause| } search_state.clause_params.each_value do |clause| op, query = adv_search_clause(clause, default_op) next unless defaults.key?(op) solr_parameters.append_boolean_query(op, query) end end |
#add_facet_fq_to_solr(solr_parameters) ⇒ Object
Add any existing facet limits, stored in app-level HTTP query as :f, to solr as appropriate :fq query.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 139 def add_facet_fq_to_solr(solr_parameters) # convert a String value into an Array if solr_parameters[:fq].is_a? String solr_parameters[:fq] = [solr_parameters[:fq]] end search_state.filters.each do |filter| if filter.config.filter_query_builder filter_query, subqueries = filter.config.filter_query_builder.call(self, filter, solr_parameters) Array(filter_query).each do |fq| solr_parameters.append_filter_query(fq) end solr_parameters.merge!(subqueries) if subqueries else filter.values.reject(&:blank?).each do |value| filter_query, subqueries = if value.is_a?(Array) facet_inclusive_value_to_fq_string(filter.key, value.reject(&:blank?)) else facet_value_to_fq_string(filter.config.key, value) end solr_parameters.append_filter_query filter_query solr_parameters.merge!(subqueries) if subqueries end end end end |
#add_facet_paging_to_solr(solr_params) ⇒ Object
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 260 def add_facet_paging_to_solr(solr_params) return if facet.blank? facet_config = blacklight_config.facet_fields[facet] solr_params[:rows] = 0 limit = if solr_params["facet.limit"] solr_params["facet.limit"].to_i else facet_config.fetch(:more_limit, blacklight_config.default_more_limit) end page = search_state.facet_page sort = search_state.facet_sort prefix = search_state.facet_prefix offset = (page - 1) * limit if facet_config.json add_solr_facet_json_params(solr_parameters, facet, facet_config, limit: limit + 1, offset: offset, sort: sort, prefix: prefix) return end # Now override with our specific things for fetching facet values facet_ex = facet_config.respond_to?(:ex) ? facet_config.ex : nil solr_params[:"facet.field"] = with_ex_local_param(facet_ex, facet_config.field) # 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_config.field}.facet.limit"] = limit + 1 solr_params[:"f.#{facet_config.field}.facet.offset"] = offset solr_params[:"f.#{facet_config.field}.facet.sort"] = sort if sort solr_params[:"f.#{facet_config.field}.facet.prefix"] = prefix if prefix end |
#add_facetting_to_solr(solr_parameters) ⇒ Object
Add appropriate Solr facetting directives in, including taking account of our facet paging/'more'. This is not about solr 'fq', this is about solr facet.* params.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 187 def add_facetting_to_solr(solr_parameters) facet_fields_to_include_in_request.each do |field_name, facet| solr_parameters[:facet] ||= true if facet.json add_solr_facet_json_params(solr_parameters, field_name, facet) next end if facet.pivot solr_parameters.append_facet_pivot with_ex_local_param(facet.ex, facet.pivot.join(",")) elsif facet.query solr_parameters.append_facet_query facet.query.values.map { |x| with_ex_local_param(facet.ex, x[:fq]) } else solr_parameters.append_facet_fields with_ex_local_param(facet.ex, facet.field) end if facet.sort solr_parameters[:"f.#{facet.field}.facet.sort"] = facet.sort end if facet.solr_params facet.solr_params.each do |k, v| solr_parameters[:"f.#{facet.field}.#{k}"] = v end end limit = facet_limit_with_pagination(field_name) solr_parameters[:"f.#{facet.field}.facet.limit"] = limit if limit end end |
#add_group_config_to_solr(solr_parameters) ⇒ Object
Remove the group parameter if we've faceted on the group field (e.g. for the full results for a group)
256 257 258 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 256 def add_group_config_to_solr solr_parameters solr_parameters[:group] = false if search_state.filter(grouped_key_for_results).any? end |
#add_paging_to_solr(solr_params) ⇒ Object
copy paging params from BL app over to solr, changing app level per_page and page to Solr rows and start.
241 242 243 244 245 246 247 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 241 def add_paging_to_solr(solr_params) rows(solr_params[:rows] || 10) if rows.nil? solr_params[:rows] = rows solr_params[:start] = start if start.nonzero? end |
#add_query_to_solr(solr_parameters) ⇒ Object
Take the user-entered query, and put it in the solr params, including config's “search field” params for current search field. also include setting spellcheck.q.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 57 def add_query_to_solr(solr_parameters) unless processor_chain.include?(:add_search_field_default_parameters) Deprecation.warn(Blacklight::Solr::SearchBuilderBehavior, 'Please include :add_search_field_default_parameters in your process chain') add_search_field_default_parameters(solr_parameters) end ## # Create Solr 'q' including the user-entered q, prefixed by any # solr LocalParams in config, using solr LocalParams syntax. # http://wiki.apache.org/solr/LocalParams ## if search_field&.query_builder.present? add_search_field_query_builder_params(solr_parameters) elsif search_field&.clause_params.present? add_search_field_with_json_query_parameters(solr_parameters) elsif search_field&.solr_local_parameters.present? add_search_field_with_local_parameters(solr_parameters) elsif search_state.query_param.is_a? Hash if search_state.query_param == @additional_filters && !processor_chain.include?(:add_additional_filters) Deprecation.warn(Blacklight::Solr::SearchBuilderBehavior, 'Expecting to see the processor step add_additional_filters; falling back to legacy query handling') add_additional_filters(solr_parameters, search_state.query_param) end elsif search_state.query_param solr_parameters.append_query search_state.query_param end end |
#add_search_field_default_parameters(solr_parameters) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 32 def add_search_field_default_parameters(solr_parameters) ### # legacy behavior of user param :qt is passed through, but over-ridden # by actual search field config if present. We might want to remove # this legacy behavior at some point. It does not seem to be currently # rspec'd. if search_state.params[:qt] Deprecation.warn(Blacklight::Solr::SearchBuilderBehavior, 'Passing the Solr qt as a parameter is deprecated.') solr_parameters[:qt] = blacklight_params[:qt] end ### # Merge in search field configured values, if present, over-writing general # defaults if search_field solr_parameters[:qt] = search_field.qt if search_field.qt solr_parameters.deep_merge!(search_field.solr_parameters) if search_field.solr_parameters end end |
#add_search_field_with_json_query_parameters(solr_parameters) ⇒ Object
104 105 106 107 108 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 104 def add_search_field_with_json_query_parameters(solr_parameters) bool_query = search_field.clause_params.transform_values { |v| v.merge(query: search_state.query_param) } solr_parameters.append_boolean_query(:must, bool_query) end |
#add_solr_facet_json_params(solr_parameters, field_name, facet, **additional_parameters) ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 168 def add_solr_facet_json_params(solr_parameters, field_name, facet, **additional_parameters) solr_parameters[:json] ||= { facet: {} } solr_parameters[:json][:facet] ||= {} field_config = facet.json.respond_to?(:reverse_merge) ? facet.json : {} field_config = field_config.reverse_merge( type: 'terms', field: facet.field, limit: facet_limit_with_pagination(field_name) ).merge(additional_parameters) solr_parameters[:json][:facet][field_name] = field_config.select { |_k, v| v.present? } end |
#add_solr_fields_to_query(solr_parameters) ⇒ Object
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 219 def add_solr_fields_to_query solr_parameters blacklight_config.show_fields.select(&method(:should_add_field_to_request?)).each_value do |field| field.solr_params.each do |k, v| solr_parameters[:"f.#{field.field}.#{k}"] = v end if field.solr_params end blacklight_config.index_fields.select(&method(:should_add_field_to_request?)).each_value do |field| if field.highlight solr_parameters[:hl] = true solr_parameters.append_highlight_field field.field end field.solr_params.each do |k, v| solr_parameters[:"f.#{field.field}.#{k}"] = v end if field.solr_params end end |
#add_sorting_to_solr(solr_parameters) ⇒ Object
copy sorting params from BL app over to solr
251 252 253 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 251 def add_sorting_to_solr(solr_parameters) solr_parameters[:sort] = sort if sort.present? end |
#adv_search_clause(clause, default_op) ⇒ Array
Returns the first element is the query operator and the second is the value to add.
127 128 129 130 131 132 133 134 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 127 def adv_search_clause(clause, default_op) op = clause[:op]&.to_sym || default_op field = (blacklight_config.search_fields || {})[clause[:field]] if clause[:field] return unless field&.clause_params && clause[:query].present? [op, field.clause_params.transform_values { |v| v.merge(query: clause[:query]) }] end |
#default_solr_parameters(solr_parameters) ⇒ Object
Start with general defaults from BL config. Need to use custom merge to dup values, to avoid later mutating the original by mistake.
20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 20 def default_solr_parameters(solr_parameters) blacklight_config.default_solr_params.each do |key, value| solr_parameters[key] ||= if value.respond_to? :deep_dup value.deep_dup elsif value.respond_to?(:dup) && value.duplicable? value.dup else value end end end |
#facet_limit_for(facet_field) ⇒ Object
Look up facet limit for given facet_field. Will look at config, and if config is 'true' will look up from Solr @response if available. If no limit is avaialble, returns nil. Used from #add_facetting_to_solr to supply f.fieldname.facet.limit values in solr request (no @response available), and used in display (with @response available) to create a facet paginator with the right limit.
309 310 311 312 313 314 315 316 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 309 def facet_limit_for(facet_field) facet = blacklight_config.facet_fields[facet_field] return if facet.blank? if facet.limit facet.limit == true ? blacklight_config.default_facet_limit : facet.limit end end |
#facet_limit_with_pagination(field_name) ⇒ Object
Support facet paging and 'more' links, by sending a facet.limit one more than what we want to page at, according to configured facet limits.
321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 321 def facet_limit_with_pagination(field_name) limit = facet_limit_for(field_name) return if limit.nil? if limit > 0 limit + 1 else limit end end |
#solr_param_quote(val, options = {}) ⇒ Object
A helper method used for generating solr LocalParams, put quotes around the term unless it's a bare-word. Escape internal quotes if needed.
337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 337 def solr_param_quote(val, = {}) val = val.to_s [:quote] ||= '"' unless val =~ /^[a-zA-Z0-9$_\-\^]+$/ val = [:quote] + # Yes, we need crazy escaping here, to deal with regexp esc too! val.gsub("'", "\\\\\'").gsub('"', "\\\\\"") + [:quote] end val end |
#with_ex_local_param(ex, value) ⇒ Object
295 296 297 298 299 300 301 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 295 def with_ex_local_param(ex, value) if ex "{!ex=#{ex}}#{value}" else value end end |