blacklight 7.15.1 → 7.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/VERSION +1 -1
- data/app/components/blacklight/advanced_search_form_component.html.erb +9 -3
- data/app/components/blacklight/advanced_search_form_component.rb +48 -35
- data/app/components/blacklight/constraints_component.html.erb +19 -3
- data/app/components/blacklight/constraints_component.rb +5 -1
- data/app/components/blacklight/content_areas_shim.rb +12 -0
- data/app/components/blacklight/document/action_component.html.erb +1 -1
- data/app/components/blacklight/document/action_component.rb +6 -1
- data/app/components/blacklight/document/actions_component.html.erb +3 -5
- data/app/components/blacklight/document/actions_component.rb +16 -2
- data/app/components/blacklight/document_component.html.erb +4 -7
- data/app/components/blacklight/document_component.rb +73 -73
- data/app/components/blacklight/document_metadata_component.html.erb +2 -2
- data/app/components/blacklight/document_metadata_component.rb +13 -2
- data/app/components/blacklight/document_title_component.html.erb +17 -0
- data/app/components/blacklight/document_title_component.rb +59 -0
- data/app/components/blacklight/facet_field_checkboxes_component.html.erb +2 -2
- data/app/components/blacklight/facet_field_component.rb +4 -1
- data/app/components/blacklight/facet_field_list_component.html.erb +2 -2
- data/app/components/blacklight/facet_field_no_layout_component.rb +4 -1
- data/app/components/blacklight/metadata_field_component.html.erb +2 -2
- data/app/components/blacklight/metadata_field_layout_component.html.erb +3 -1
- data/app/components/blacklight/metadata_field_layout_component.rb +26 -1
- data/app/components/blacklight/response/view_type_button_component.html.erb +4 -0
- data/app/components/blacklight/response/view_type_button_component.rb +38 -0
- data/app/components/blacklight/response/view_type_component.html.erb +2 -5
- data/app/components/blacklight/response/view_type_component.rb +9 -13
- data/app/components/blacklight/search_bar_component.rb +9 -2
- data/app/components/blacklight/system/dropdown_component.html.erb +4 -7
- data/app/components/blacklight/system/dropdown_component.rb +24 -0
- data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
- data/app/components/blacklight/system/flash_message_component.rb +7 -1
- data/app/components/blacklight/system/modal_component.rb +7 -1
- data/app/controllers/concerns/blacklight/catalog.rb +1 -1
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +3 -4
- data/app/helpers/blacklight/catalog_helper_behavior.rb +2 -0
- data/app/helpers/blacklight/component_helper_behavior.rb +2 -2
- data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
- data/app/presenters/blacklight/document_presenter.rb +8 -4
- data/app/services/blacklight/search_service.rb +1 -1
- data/app/views/bookmarks/_tools.html.erb +1 -1
- data/app/views/catalog/_citation.html.erb +1 -1
- data/app/views/catalog/_document.html.erb +2 -2
- data/app/views/catalog/_facet_layout.html.erb +2 -2
- data/app/views/catalog/_show_main_content.html.erb +3 -3
- data/app/views/catalog/email.html.erb +2 -2
- data/app/views/catalog/email_success.html.erb +1 -1
- data/app/views/catalog/facet.html.erb +3 -3
- data/app/views/catalog/sms.html.erb +2 -2
- data/app/views/catalog/sms_success.html.erb +1 -1
- data/blacklight.gemspec +1 -1
- data/config/locales/blacklight.de.yml +2 -2
- data/lib/blacklight/configuration.rb +50 -5
- data/lib/blacklight/configuration/view_config.rb +18 -5
- data/lib/blacklight/engine.rb +3 -1
- data/lib/blacklight/open_struct_with_hash_access.rb +22 -1
- data/lib/blacklight/search_state.rb +2 -2
- data/lib/blacklight/solr/facet_paginator.rb +2 -0
- data/lib/blacklight/solr/request.rb +31 -0
- data/lib/blacklight/solr/response.rb +2 -16
- data/lib/blacklight/solr/response/facets.rb +76 -22
- data/lib/blacklight/solr/response/params.rb +104 -0
- data/lib/blacklight/solr/search_builder_behavior.rb +57 -27
- data/lib/generators/blacklight/assets_generator.rb +6 -2
- data/lib/generators/blacklight/user_generator.rb +1 -1
- data/spec/components/blacklight/document_component_spec.rb +3 -3
- data/spec/lib/blacklight/configuration/view_config_spec.rb +1 -1
- data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +20 -0
- data/spec/models/blacklight/configuration_spec.rb +64 -0
- data/spec/models/blacklight/solr/facet_paginator_spec.rb +4 -0
- data/spec/models/blacklight/solr/request_spec.rb +62 -29
- data/spec/models/blacklight/solr/response/facets_spec.rb +109 -0
- data/spec/models/blacklight/solr/response_spec.rb +10 -0
- data/spec/models/blacklight/solr/search_builder_spec.rb +49 -0
- data/spec/views/catalog/_view_type_group.html.erb_spec.rb +8 -9
- data/spec/views/catalog/index.atom.builder_spec.rb +1 -1
- metadata +10 -4
@@ -115,9 +115,9 @@ module Blacklight
|
|
115
115
|
# documents
|
116
116
|
def url_for_document(doc, options = {})
|
117
117
|
if respond_to?(:blacklight_config) &&
|
118
|
-
blacklight_config.show.route &&
|
118
|
+
blacklight_config.view_config(:show).route &&
|
119
119
|
(!doc.respond_to?(:to_model) || doc.to_model.is_a?(SolrDocument))
|
120
|
-
route = blacklight_config.show.route.merge(action: :show, id: doc).merge(options)
|
120
|
+
route = blacklight_config.view_config(:show).route.merge(action: :show, id: doc).merge(options)
|
121
121
|
route[:controller] = params[:controller] if route[:controller] == :current
|
122
122
|
route
|
123
123
|
else
|
@@ -17,6 +17,37 @@ class Blacklight::Solr::Request < ActiveSupport::HashWithIndifferentAccess
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
def append_query(query)
|
21
|
+
if self['q'] || dig(:json, :query, :bool)
|
22
|
+
self[:json] ||= { query: { bool: { must: [] } } }
|
23
|
+
self[:json][:query] ||= { bool: { must: [] } }
|
24
|
+
self[:json][:query][:bool][:must] << query
|
25
|
+
|
26
|
+
if self['q']
|
27
|
+
self[:json][:query][:bool][:must] << self['q']
|
28
|
+
delete 'q'
|
29
|
+
end
|
30
|
+
else
|
31
|
+
self['q'] = query
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def append_boolean_query(bool_operator, query)
|
36
|
+
return if query.blank?
|
37
|
+
|
38
|
+
self[:json] ||= { query: { bool: { bool_operator => [] } } }
|
39
|
+
self[:json][:query] ||= { bool: { bool_operator => [] } }
|
40
|
+
self[:json][:query][:bool][bool_operator] ||= []
|
41
|
+
|
42
|
+
if self['q']
|
43
|
+
self[:json][:query][:bool][:must] ||= []
|
44
|
+
self[:json][:query][:bool][:must] << self['q']
|
45
|
+
delete 'q'
|
46
|
+
end
|
47
|
+
|
48
|
+
self[:json][:query][:bool][bool_operator] << query
|
49
|
+
end
|
50
|
+
|
20
51
|
def append_filter_query(query)
|
21
52
|
self['fq'] << query
|
22
53
|
end
|
@@ -9,6 +9,7 @@ class Blacklight::Solr::Response < ActiveSupport::HashWithIndifferentAccess
|
|
9
9
|
autoload :MoreLikeThis
|
10
10
|
autoload :GroupResponse
|
11
11
|
autoload :Group
|
12
|
+
autoload :Params
|
12
13
|
end
|
13
14
|
|
14
15
|
include PaginationMethods
|
@@ -16,6 +17,7 @@ class Blacklight::Solr::Response < ActiveSupport::HashWithIndifferentAccess
|
|
16
17
|
include Facets
|
17
18
|
include Response
|
18
19
|
include MoreLikeThis
|
20
|
+
include Params
|
19
21
|
|
20
22
|
attr_reader :request_params
|
21
23
|
attr_accessor :blacklight_config, :options
|
@@ -33,22 +35,6 @@ class Blacklight::Solr::Response < ActiveSupport::HashWithIndifferentAccess
|
|
33
35
|
self['responseHeader'] || {}
|
34
36
|
end
|
35
37
|
|
36
|
-
def params
|
37
|
-
header['params'] || request_params
|
38
|
-
end
|
39
|
-
|
40
|
-
def start
|
41
|
-
params[:start].to_i
|
42
|
-
end
|
43
|
-
|
44
|
-
def rows
|
45
|
-
params[:rows].to_i
|
46
|
-
end
|
47
|
-
|
48
|
-
def sort
|
49
|
-
params[:sort]
|
50
|
-
end
|
51
|
-
|
52
38
|
def documents
|
53
39
|
@documents ||= (response['docs'] || []).collect { |doc| document_factory.build(doc, self, options) }
|
54
40
|
end
|
@@ -29,6 +29,7 @@ module Blacklight::Solr::Response::Facets
|
|
29
29
|
# represents a facet; which is a field and its values
|
30
30
|
class FacetField
|
31
31
|
attr_reader :name, :items
|
32
|
+
attr_accessor :missing
|
32
33
|
|
33
34
|
def initialize name, items, options = {}
|
34
35
|
@name = name
|
@@ -52,6 +53,14 @@ module Blacklight::Solr::Response::Facets
|
|
52
53
|
@options[:prefix] || solr_default_prefix
|
53
54
|
end
|
54
55
|
|
56
|
+
def type
|
57
|
+
@options[:type] || 'terms'
|
58
|
+
end
|
59
|
+
|
60
|
+
def data
|
61
|
+
@options[:data] || {}
|
62
|
+
end
|
63
|
+
|
55
64
|
def index?
|
56
65
|
sort == 'index'
|
57
66
|
end
|
@@ -90,7 +99,7 @@ module Blacklight::Solr::Response::Facets
|
|
90
99
|
# Get all the Solr facet data (fields, queries, pivots) as a hash keyed by
|
91
100
|
# both the Solr field name and/or by the blacklight field name
|
92
101
|
def aggregations
|
93
|
-
@aggregations ||= {}.merge(facet_field_aggregations).merge(facet_query_aggregations).merge(facet_pivot_aggregations)
|
102
|
+
@aggregations ||= {}.merge(facet_field_aggregations).merge(facet_query_aggregations).merge(facet_pivot_aggregations).merge(json_facet_aggregations)
|
94
103
|
end
|
95
104
|
|
96
105
|
def facet_counts
|
@@ -159,19 +168,24 @@ module Blacklight::Solr::Response::Facets
|
|
159
168
|
items = values.map do |value, hits|
|
160
169
|
i = FacetItem.new(value: value, hits: hits)
|
161
170
|
|
162
|
-
# solr facet.missing serialization
|
171
|
+
# legacy solr facet.missing serialization
|
163
172
|
if value.nil?
|
164
173
|
i.label = I18n.t(:"blacklight.search.fields.facet.missing.#{facet_field_name}", default: [:"blacklight.search.facets.missing"])
|
165
174
|
i.fq = "-#{facet_field_name}:[* TO *]"
|
175
|
+
i.missing = true
|
166
176
|
end
|
167
177
|
|
168
178
|
i
|
169
179
|
end
|
170
180
|
|
171
181
|
options = facet_field_aggregation_options(facet_field_name)
|
172
|
-
|
173
|
-
|
174
|
-
|
182
|
+
facet_field = FacetField.new(facet_field_name, items, options)
|
183
|
+
|
184
|
+
if values[nil]
|
185
|
+
facet_field.missing = items.find(&:missing)
|
186
|
+
end
|
187
|
+
|
188
|
+
hash[facet_field_name] = facet_field
|
175
189
|
|
176
190
|
# alias all the possible blacklight config names..
|
177
191
|
blacklight_config.facet_fields.select { |_k, v| v.field == facet_field_name }.each_key do |key|
|
@@ -180,23 +194,6 @@ module Blacklight::Solr::Response::Facets
|
|
180
194
|
end
|
181
195
|
end
|
182
196
|
|
183
|
-
def facet_field_aggregation_options(facet_field_name)
|
184
|
-
options = {}
|
185
|
-
options[:sort] = (params[:"f.#{facet_field_name}.facet.sort"] || params[:'facet.sort'])
|
186
|
-
if params[:"f.#{facet_field_name}.facet.limit"] || params[:"facet.limit"]
|
187
|
-
options[:limit] = (params[:"f.#{facet_field_name}.facet.limit"] || params[:"facet.limit"]).to_i
|
188
|
-
end
|
189
|
-
|
190
|
-
if params[:"f.#{facet_field_name}.facet.offset"] || params[:'facet.offset']
|
191
|
-
options[:offset] = (params[:"f.#{facet_field_name}.facet.offset"] || params[:'facet.offset']).to_i
|
192
|
-
end
|
193
|
-
|
194
|
-
if params[:"f.#{facet_field_name}.facet.prefix"] || params[:'facet.prefix']
|
195
|
-
options[:prefix] = (params[:"f.#{facet_field_name}.facet.prefix"] || params[:'facet.prefix'])
|
196
|
-
end
|
197
|
-
options
|
198
|
-
end
|
199
|
-
|
200
197
|
##
|
201
198
|
# Aggregate Solr's facet_query response into the virtual facet fields defined
|
202
199
|
# in the blacklight configuration
|
@@ -211,12 +208,28 @@ module Blacklight::Solr::Response::Facets
|
|
211
208
|
Blacklight::Solr::Response::Facets::FacetItem.new(value: key, hits: hits, label: facet_field.query[key][:label])
|
212
209
|
end
|
213
210
|
|
211
|
+
items += facet_query_aggregations_from_json(facet_field)
|
212
|
+
|
214
213
|
items = items.sort_by(&:hits).reverse if facet_field.sort && facet_field.sort.to_sym == :count
|
215
214
|
|
216
215
|
hash[field_name] = Blacklight::Solr::Response::Facets::FacetField.new field_name, items
|
217
216
|
end
|
218
217
|
end
|
219
218
|
|
219
|
+
def facet_query_aggregations_from_json(facet_field)
|
220
|
+
return [] unless self['facets']
|
221
|
+
|
222
|
+
salient_facet_queries = facet_field.query.map { |_k, x| x[:fq] }
|
223
|
+
|
224
|
+
relevant_facet_data = self['facets'].select { |k, _v| salient_facet_queries.include?(k) }.reject { |_key, data| data['count'].zero? }
|
225
|
+
|
226
|
+
relevant_facet_data.map do |key, data|
|
227
|
+
salient_fields = facet_field.query.select { |_key, val| val[:fq] == key }
|
228
|
+
facet_key = ((salient_fields.keys if salient_fields.respond_to? :keys) || salient_fields.first).first
|
229
|
+
Blacklight::Solr::Response::Facets::FacetItem.new(value: facet_key, hits: data[:count], label: facet_field.query[facet_key][:label])
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
220
233
|
##
|
221
234
|
# Convert Solr's facet_pivot response into
|
222
235
|
# a hash of Blacklight::Solr::Response::Facet::FacetField objects
|
@@ -244,4 +257,45 @@ module Blacklight::Solr::Response::Facets
|
|
244
257
|
|
245
258
|
Blacklight::Solr::Response::Facets::FacetItem.new(value: lst[:value], hits: lst[:count], field: lst[:field], items: items, fq: parent_fq)
|
246
259
|
end
|
260
|
+
|
261
|
+
def construct_json_nested_facet_fields(bucket, parent_fq = {})
|
262
|
+
bucket.select { |_, nested| nested.is_a?(Hash) && nested.key?('buckets') }.map do |facet_field_name, nested|
|
263
|
+
nested['buckets'].map do |subbucket|
|
264
|
+
i = Blacklight::Solr::Response::Facets::FacetItem.new(field: facet_field_name, value: subbucket['val'], hits: subbucket['count'], fq: parent_fq, data: subbucket)
|
265
|
+
|
266
|
+
i.items = construct_json_nested_facet_fields(subbucket, parent_fq.merge(key => subbucket['val'])) if has_json_nested_facets?(subbucket)
|
267
|
+
i
|
268
|
+
end
|
269
|
+
end.flatten
|
270
|
+
end
|
271
|
+
|
272
|
+
def has_json_nested_facets?(bucket)
|
273
|
+
bucket.any? { |_, nested| nested.is_a?(Hash) && nested.key?('buckets') }
|
274
|
+
end
|
275
|
+
|
276
|
+
def json_facet_aggregations
|
277
|
+
return {} unless self['facets']
|
278
|
+
|
279
|
+
self['facets'].each_with_object({}) do |(facet_field_name, data), hash|
|
280
|
+
next if facet_field_name == 'count'
|
281
|
+
|
282
|
+
items = (data['buckets'] || []).map do |bucket|
|
283
|
+
i = Blacklight::Solr::Response::Facets::FacetItem.new(value: bucket['val'], hits: bucket['count'], data: bucket)
|
284
|
+
|
285
|
+
i.items = construct_json_nested_facet_fields(bucket, facet_field_name => bucket['val']) if has_json_nested_facets?(bucket)
|
286
|
+
|
287
|
+
i
|
288
|
+
end
|
289
|
+
|
290
|
+
options = facet_field_aggregation_options(facet_field_name).merge(data: data)
|
291
|
+
facet_field = FacetField.new(facet_field_name, items, options)
|
292
|
+
|
293
|
+
facet_field.missing = Blacklight::Solr::Response::Facets::FacetItem.new(
|
294
|
+
hits: data.dig('missing', 'count'),
|
295
|
+
data: data['missing']
|
296
|
+
) if data['missing']
|
297
|
+
|
298
|
+
hash[facet_field_name] = facet_field
|
299
|
+
end
|
300
|
+
end
|
247
301
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Blacklight::Solr::Response::Params
|
3
|
+
# From https://solr.apache.org/guide/8_8/json-request-api.html#supported-properties-and-syntax
|
4
|
+
QUERY_PARAMETER_TO_JSON_PARAMETER_MAPPING = {
|
5
|
+
q: :query,
|
6
|
+
fq: :filter,
|
7
|
+
start: :offset,
|
8
|
+
rows: :limit,
|
9
|
+
fl: :fields,
|
10
|
+
sort: :sort
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
def params
|
14
|
+
header['params'] || request_params
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
search_builder&.start || single_valued_param(:start).to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
def rows
|
22
|
+
search_builder&.rows || single_valued_param(:rows).to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
def sort
|
26
|
+
search_builder&.sort || single_valued_param(:sort)
|
27
|
+
end
|
28
|
+
|
29
|
+
def facet_field_aggregation_options(facet_field_name)
|
30
|
+
defaults = {
|
31
|
+
sort: single_valued_param(:'facet.sort'),
|
32
|
+
limit: single_valued_param(:"facet.limit")&.to_i || 100,
|
33
|
+
offset: single_valued_param(:"facet.offset")&.to_i || 0,
|
34
|
+
prefix: single_valued_param(:"facet.prefix")
|
35
|
+
}
|
36
|
+
|
37
|
+
json_facet = json_params.dig('facet', facet_field_name)&.slice(:limit, :offset, :prefix, :sort)&.symbolize_keys || {}
|
38
|
+
|
39
|
+
param_facet = {
|
40
|
+
sort: single_valued_param(:"f.#{facet_field_name}.facet.sort"),
|
41
|
+
limit: single_valued_param(:"f.#{facet_field_name}.facet.limit")&.to_i,
|
42
|
+
offset: single_valued_param(:"f.#{facet_field_name}.facet.offset")&.to_i,
|
43
|
+
prefix: single_valued_param(:"f.#{facet_field_name}.facet.prefix")
|
44
|
+
}.reject { |_k, v| v.nil? }
|
45
|
+
|
46
|
+
options = defaults.merge(json_facet).merge(param_facet)
|
47
|
+
options[:sort] ||= options[:limit].positive? ? 'count' : 'index'
|
48
|
+
|
49
|
+
options
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def search_builder
|
55
|
+
request_params if request_params.is_a?(Blacklight::SearchBuilder)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Extract JSON Request API parameters from the response header or the request itself
|
59
|
+
def json_params
|
60
|
+
encoded_json_params = header&.dig('params', 'json')
|
61
|
+
|
62
|
+
return request_params['json'] || {} if encoded_json_params.blank?
|
63
|
+
|
64
|
+
@json_params ||= JSON.parse(encoded_json_params).with_indifferent_access
|
65
|
+
end
|
66
|
+
|
67
|
+
# Handle merging solr parameters from the myriad of ways they may be expressed by applying the single-value
|
68
|
+
# precedence logic:
|
69
|
+
#
|
70
|
+
# From https://solr.apache.org/guide/8_8/json-request-api.html#json-parameter-merging :
|
71
|
+
# When multiple parameter values conflict with one another a single value is chosen based on the following precedence rules:
|
72
|
+
# - Traditional query parameters (q, rows, etc.) take first precedence and are used over any other specified values.
|
73
|
+
# - json-prefixed query parameters are considered next.
|
74
|
+
# - Values specified in the JSON request body have the lowest precedence and are only used if specified nowhere else.
|
75
|
+
#
|
76
|
+
# @param [String] key the solr parameter to use
|
77
|
+
def single_valued_param(key)
|
78
|
+
json_key = QUERY_PARAMETER_TO_JSON_PARAMETER_MAPPING[key]
|
79
|
+
|
80
|
+
params[key] ||
|
81
|
+
params["json.#{key}"] ||
|
82
|
+
json_params[json_key || key] ||
|
83
|
+
json_params.dig(:params, key) ||
|
84
|
+
json_params.dig(:params, "json.#{key}")
|
85
|
+
end
|
86
|
+
|
87
|
+
# Merge together multi-valued solr parameters from the myriad of ways they may be expressed.
|
88
|
+
# Unlike single-valued parameters, this merges all the values across the params.
|
89
|
+
#
|
90
|
+
# @param [String] key the solr parameter to use
|
91
|
+
def multivalued_param(key)
|
92
|
+
json_key = QUERY_PARAMETER_TO_JSON_PARAMETER_MAPPING[key]
|
93
|
+
|
94
|
+
[
|
95
|
+
params[key],
|
96
|
+
params["json.#{key}"],
|
97
|
+
json_params[json_key || key],
|
98
|
+
json_params.dig(:params, key),
|
99
|
+
json_params.dig(:params, "json.#{key}")
|
100
|
+
].select(&:present?).inject([]) do |memo, arr|
|
101
|
+
memo.concat(Array.wrap(arr))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -59,12 +59,14 @@ module Blacklight::Solr
|
|
59
59
|
##
|
60
60
|
if search_field&.query_builder.present?
|
61
61
|
add_search_field_query_builder_params(solr_parameters)
|
62
|
+
elsif search_field&.clause_params.present?
|
63
|
+
add_search_field_with_json_query_parameters(solr_parameters)
|
62
64
|
elsif search_field&.solr_local_parameters.present?
|
63
65
|
add_search_field_with_local_parameters(solr_parameters)
|
64
66
|
elsif search_state.query_param.is_a? Hash
|
65
67
|
add_additional_filters(solr_parameters, search_state.query_param)
|
66
68
|
elsif search_state.query_param
|
67
|
-
solr_parameters
|
69
|
+
solr_parameters.append_query search_state.query_param
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
@@ -73,39 +75,41 @@ module Blacklight::Solr
|
|
73
75
|
|
74
76
|
return if q.blank?
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
78
|
+
if q.values.any?(&:blank?)
|
79
|
+
# if any field parameters are empty, exclude _all_ results
|
80
|
+
solr_parameters.append_query "{!lucene}NOT *:*"
|
81
|
+
else
|
82
|
+
composed_query = q.map do |field, values|
|
83
|
+
"#{field}:(#{Array(values).map { |x| solr_param_quote(x) }.join(' OR ')})"
|
84
|
+
end.join(" AND ")
|
85
|
+
|
86
|
+
solr_parameters.append_query "{!lucene}#{composed_query}"
|
87
|
+
end
|
84
88
|
|
85
89
|
solr_parameters[:defType] = 'lucene'
|
86
90
|
solr_parameters[:spellcheck] = 'false'
|
87
91
|
end
|
88
92
|
|
93
|
+
def add_search_field_with_json_query_parameters(solr_parameters)
|
94
|
+
bool_query = search_field.clause_params.transform_values { |v| v.merge(query: search_state.query_param) }
|
95
|
+
|
96
|
+
solr_parameters.append_boolean_query(:must, bool_query)
|
97
|
+
end
|
98
|
+
|
89
99
|
# Transform "clause" parameters into the Solr JSON Query DSL
|
90
100
|
def add_adv_search_clauses(solr_parameters)
|
91
101
|
return if search_state.clause_params.blank?
|
92
102
|
|
93
103
|
defaults = { must: [], must_not: [], should: [] }
|
94
|
-
bool_query = (solr_parameters.dig(:json, :query, :bool) || {}).reverse_merge(defaults)
|
95
|
-
|
96
104
|
default_op = blacklight_params[:op]&.to_sym || :must
|
105
|
+
solr_parameters[:mm] = 1 if default_op == :should && search_state.clause_params.values.any? { |clause| }
|
97
106
|
|
98
107
|
search_state.clause_params.each_value do |clause|
|
99
108
|
op, query = adv_search_clause(clause, default_op)
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
return if bool_query.values.all?(&:blank?)
|
109
|
+
next unless defaults.key?(op)
|
104
110
|
|
105
|
-
|
106
|
-
|
107
|
-
solr_parameters[:json][:query] ||= { bool: {} }
|
108
|
-
solr_parameters[:json][:query][:bool] = bool_query.reject { |_k, v| v.blank? }
|
111
|
+
solr_parameters.append_boolean_query(op, query)
|
112
|
+
end
|
109
113
|
end
|
110
114
|
|
111
115
|
# @return [Array] the first element is the query operator and the second is the value to add
|
@@ -131,7 +135,7 @@ module Blacklight::Solr
|
|
131
135
|
if filter.config.filter_query_builder
|
132
136
|
filter_query, subqueries = filter.config.filter_query_builder.call(self, filter, solr_parameters)
|
133
137
|
|
134
|
-
solr_parameters.append_filter_query(filter_query)
|
138
|
+
solr_parameters.append_filter_query(filter_query) if filter_query
|
135
139
|
solr_parameters.merge!(subqueries) if subqueries
|
136
140
|
else
|
137
141
|
filter.values.reject(&:blank?).each do |value|
|
@@ -148,6 +152,21 @@ module Blacklight::Solr
|
|
148
152
|
end
|
149
153
|
end
|
150
154
|
|
155
|
+
def add_solr_facet_json_params(solr_parameters, field_name, facet, **additional_parameters)
|
156
|
+
solr_parameters[:json] ||= { facet: {} }
|
157
|
+
solr_parameters[:json][:facet] ||= {}
|
158
|
+
|
159
|
+
field_config = facet.json.respond_to?(:reverse_merge) ? facet.json : {}
|
160
|
+
|
161
|
+
field_config = field_config.reverse_merge(
|
162
|
+
type: 'terms',
|
163
|
+
field: facet.field,
|
164
|
+
limit: facet_limit_with_pagination(field_name)
|
165
|
+
).merge(additional_parameters)
|
166
|
+
|
167
|
+
solr_parameters[:json][:facet][field_name] = field_config.select { |_k, v| v.present? }
|
168
|
+
end
|
169
|
+
|
151
170
|
##
|
152
171
|
# Add appropriate Solr facetting directives in, including
|
153
172
|
# taking account of our facet paging/'more'. This is not
|
@@ -156,6 +175,11 @@ module Blacklight::Solr
|
|
156
175
|
facet_fields_to_include_in_request.each do |field_name, facet|
|
157
176
|
solr_parameters[:facet] ||= true
|
158
177
|
|
178
|
+
if facet.json
|
179
|
+
add_solr_facet_json_params(solr_parameters, field_name, facet)
|
180
|
+
next
|
181
|
+
end
|
182
|
+
|
159
183
|
if facet.pivot
|
160
184
|
solr_parameters.append_facet_pivot with_ex_local_param(facet.ex, facet.pivot.join(","))
|
161
185
|
elsif facet.query
|
@@ -225,9 +249,7 @@ module Blacklight::Solr
|
|
225
249
|
|
226
250
|
facet_config = blacklight_config.facet_fields[facet]
|
227
251
|
|
228
|
-
|
229
|
-
facet_ex = facet_config.respond_to?(:ex) ? facet_config.ex : nil
|
230
|
-
solr_params[:"facet.field"] = with_ex_local_param(facet_ex, facet_config.field)
|
252
|
+
solr_params[:rows] = 0
|
231
253
|
|
232
254
|
limit = if solr_params["facet.limit"]
|
233
255
|
solr_params["facet.limit"].to_i
|
@@ -240,13 +262,21 @@ module Blacklight::Solr
|
|
240
262
|
prefix = search_state.facet_prefix
|
241
263
|
offset = (page - 1) * limit
|
242
264
|
|
265
|
+
if facet_config.json
|
266
|
+
add_solr_facet_json_params(solr_parameters, facet, facet_config, limit: limit + 1, offset: offset, sort: sort, prefix: prefix)
|
267
|
+
return
|
268
|
+
end
|
269
|
+
|
270
|
+
# Now override with our specific things for fetching facet values
|
271
|
+
facet_ex = facet_config.respond_to?(:ex) ? facet_config.ex : nil
|
272
|
+
solr_params[:"facet.field"] = with_ex_local_param(facet_ex, facet_config.field)
|
273
|
+
|
243
274
|
# Need to set as f.facet_field.facet.* to make sure we
|
244
275
|
# override any field-specific default in the solr request handler.
|
245
276
|
solr_params[:"f.#{facet_config.field}.facet.limit"] = limit + 1
|
246
277
|
solr_params[:"f.#{facet_config.field}.facet.offset"] = offset
|
247
278
|
solr_params[:"f.#{facet_config.field}.facet.sort"] = sort if sort
|
248
279
|
solr_params[:"f.#{facet_config.field}.facet.prefix"] = prefix if prefix
|
249
|
-
solr_params[:rows] = 0
|
250
280
|
end
|
251
281
|
|
252
282
|
def with_ex_local_param(ex, value)
|
@@ -367,7 +397,7 @@ module Blacklight::Solr
|
|
367
397
|
##
|
368
398
|
# The key to use to retrieve the grouped field to display
|
369
399
|
def grouped_key_for_results
|
370
|
-
blacklight_config.index.group
|
400
|
+
blacklight_config.view_config(action_name: :index).group
|
371
401
|
end
|
372
402
|
|
373
403
|
def facet_fields_to_include_in_request
|
@@ -385,7 +415,7 @@ module Blacklight::Solr
|
|
385
415
|
def add_search_field_query_builder_params(solr_parameters)
|
386
416
|
q, additional_parameters = search_field.query_builder.call(self, search_field, solr_parameters)
|
387
417
|
|
388
|
-
solr_parameters
|
418
|
+
solr_parameters.append_query q
|
389
419
|
solr_parameters.merge!(additional_parameters) if additional_parameters
|
390
420
|
end
|
391
421
|
|
@@ -393,7 +423,7 @@ module Blacklight::Solr
|
|
393
423
|
local_params = search_field.solr_local_parameters.map do |key, val|
|
394
424
|
key.to_s + "=" + solr_param_quote(val, quote: "'")
|
395
425
|
end.join(" ")
|
396
|
-
solr_parameters
|
426
|
+
solr_parameters.append_query "{!#{local_params}}#{search_state.query_param}"
|
397
427
|
|
398
428
|
##
|
399
429
|
# Set Solr spellcheck.q to be original user-entered query, without
|