lib/blacklight/solr/search_builder_behavior.rb in blacklight-7.16.0 vs lib/blacklight/solr/search_builder_behavior.rb in blacklight-7.17.0

- old
+ new

@@ -64,60 +64,54 @@ elsif search_field&.solr_local_parameters.present? add_search_field_with_local_parameters(solr_parameters) elsif search_state.query_param.is_a? Hash add_additional_filters(solr_parameters, search_state.query_param) elsif search_state.query_param - solr_parameters[:q] = search_state.query_param + solr_parameters.append_query search_state.query_param end end def add_additional_filters(solr_parameters, additional_filters = nil) q = additional_filters || @additional_filters return if q.blank? - solr_parameters[:q] = if q.values.any?(&:blank?) - # if any field parameters are empty, exclude _all_ results - "{!lucene}NOT *:*" - else - "{!lucene}" + q.map do |field, values| - "#{field}:(#{Array(values).map { |x| solr_param_quote(x) }.join(' OR ')})" - end.join(" AND ") - end + 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 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[:json] ||= { query: { bool: { must: [] } } } - solr_parameters[:json][:query] ||= { bool: { must: [] } } - solr_parameters[:json][:query][:bool][:must] << bool_query + solr_parameters.append_boolean_query(:must, bool_query) end # Transform "clause" parameters into the Solr JSON Query DSL def add_adv_search_clauses(solr_parameters) return if search_state.clause_params.blank? defaults = { must: [], must_not: [], should: [] } - bool_query = (solr_parameters.dig(:json, :query, :bool) || {}).reverse_merge(defaults) - 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) - bool_query[op] << query if defaults.key?(op) && query - end + next unless defaults.key?(op) - return if bool_query.values.all?(&:blank?) - - solr_parameters[:mm] = 1 if default_op == :should - solr_parameters[:json] ||= { query: { bool: {} } } - solr_parameters[:json][:query] ||= { bool: {} } - solr_parameters[:json][:query][:bool] = bool_query.reject { |_k, v| v.blank? } + solr_parameters.append_boolean_query(op, query) + end end # @return [Array] the first element is the query operator and the second is the value to add def adv_search_clause(clause, default_op) op = clause[:op]&.to_sym || default_op @@ -139,11 +133,11 @@ 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) - solr_parameters.append_filter_query(filter_query) + solr_parameters.append_filter_query(filter_query) if filter_query 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?)) @@ -156,18 +150,38 @@ end end end end + 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 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. 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 @@ -233,13 +247,11 @@ def add_facet_paging_to_solr(solr_params) return if facet.blank? facet_config = blacklight_config.facet_fields[facet] - # 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) + 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) @@ -248,17 +260,25 @@ 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 - solr_params[:rows] = 0 end def with_ex_local_param(ex, value) if ex "{!ex=#{ex}}#{value}" @@ -393,18 +413,18 @@ end def add_search_field_query_builder_params(solr_parameters) q, additional_parameters = search_field.query_builder.call(self, search_field, solr_parameters) - solr_parameters[:q] = q + solr_parameters.append_query q solr_parameters.merge!(additional_parameters) if additional_parameters end def add_search_field_with_local_parameters(solr_parameters) local_params = search_field.solr_local_parameters.map do |key, val| key.to_s + "=" + solr_param_quote(val, quote: "'") end.join(" ") - solr_parameters[:q] = "{!#{local_params}}#{search_state.query_param}" + solr_parameters.append_query "{!#{local_params}}#{search_state.query_param}" ## # Set Solr spellcheck.q to be original user-entered query, without # our local params, otherwise it'll try and spellcheck the local # params!