Module: Blacklight::Solr::SearchBuilderBehavior
- Extended by:
- ActiveSupport::Concern
- Included in:
- SearchBuilder
- 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
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 65 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
95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 95 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.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 123 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.compact_blank.each do |value| filter_query, subqueries = if value.is_a?(Array) facet_inclusive_value_to_fq_string(filter.key, value.compact_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
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 244 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.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 171 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)
240 241 242 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 240 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.
225 226 227 228 229 230 231 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 225 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.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 48 def add_query_to_solr(solr_parameters) ## # 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) solr_parameters.append_query search_state.query_param end end |
#add_search_field_default_parameters(solr_parameters) ⇒ Object
33 34 35 36 37 38 39 40 41 42 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 33 def add_search_field_default_parameters(solr_parameters) ### # 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
85 86 87 88 89 90 91 92 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 85 def add_search_field_with_json_query_parameters(solr_parameters) return unless search_state.query_param bool_query = search_field.clause_params.transform_values { |v| v.merge(query: search_state.query_param) } solr_parameters["spellcheck.q"] ||= 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
152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 152 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.compact_blank end |
#add_solr_fields_to_query(solr_parameters) ⇒ Object
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 203 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
235 236 237 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 235 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.
111 112 113 114 115 116 117 118 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 111 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.
21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 21 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.
293 294 295 296 297 298 299 300 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 293 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.
305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 305 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.
321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 321 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
279 280 281 282 283 284 285 |
# File 'lib/blacklight/solr/search_builder_behavior.rb', line 279 def with_ex_local_param(ex, value) if ex "{!ex=#{ex}}#{value}" else value end end |