blacklight_advanced_search 6.4.1 → 8.0.0.alpha2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +125 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -2
- data/.rubocop_todo.yml +6 -374
- data/Gemfile +3 -8
- data/README.md +46 -60
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/blacklight_advanced_search.gemspec +6 -7
- data/config/routes.rb +1 -1
- data/lib/blacklight_advanced_search/advanced_query_parser.rb +24 -38
- data/lib/blacklight_advanced_search/advanced_search_builder.rb +27 -24
- data/lib/blacklight_advanced_search/controller.rb +15 -16
- data/lib/blacklight_advanced_search/engine.rb +0 -1
- data/lib/blacklight_advanced_search/redirect_legacy_params_filter.rb +24 -7
- data/lib/blacklight_advanced_search.rb +0 -4
- data/lib/generators/blacklight_advanced_search/install_generator.rb +3 -37
- data/lib/parsing_nesting/grammar.rb +0 -12
- data/solr/conf/schema.xml +326 -573
- data/solr/conf/solrconfig.xml +80 -294
- data/spec/features/blacklight_advanced_search_form_spec.rb +13 -18
- data/spec/lib/advanced_search_builder_spec.rb +11 -9
- data/spec/spec_helper.rb +46 -14
- data/spec/test_app_templates/app/controllers/catalog_controller.rb +5 -7
- metadata +41 -62
- data/.travis.yml +0 -21
- data/app/assets/javascripts/blacklight_advanced_search.js +0 -5
- data/app/assets/stylesheets/blacklight_advanced_search/advanced_results.css +0 -21
- data/app/assets/stylesheets/blacklight_advanced_search/blacklight_advanced_search_styles.css.scss +0 -58
- data/app/assets/stylesheets/blacklight_advanced_search.css +0 -6
- data/app/controllers/advanced_controller.rb +0 -25
- data/app/controllers/blacklight_advanced_search/advanced_controller.rb +0 -25
- data/app/helpers/advanced_helper.rb +0 -4
- data/app/helpers/blacklight_advanced_search/advanced_helper_behavior.rb +0 -57
- data/app/views/advanced/_advanced_search_facets.html.erb +0 -16
- data/app/views/advanced/_advanced_search_facets_as_select.html.erb +0 -30
- data/app/views/advanced/_advanced_search_fields.html.erb +0 -8
- data/app/views/advanced/_advanced_search_form.html.erb +0 -43
- data/app/views/advanced/_advanced_search_help.html.erb +0 -24
- data/app/views/advanced/_advanced_search_submit_btns.html.erb +0 -12
- data/app/views/advanced/_facet_limit.html.erb +0 -15
- data/app/views/advanced/index.html.erb +0 -21
- data/app/views/blacklight_advanced_search/_facet_limit.html.erb +0 -16
- data/config/jetty.yml +0 -4
- data/config/locales/blacklight_advanced_search.en.yml +0 -12
- data/lib/blacklight_advanced_search/catalog_helper_override.rb +0 -30
- data/lib/blacklight_advanced_search/filter_parser.rb +0 -11
- data/lib/blacklight_advanced_search/parsing_nesting_parser.rb +0 -15
- data/lib/blacklight_advanced_search/render_constraints_override.rb +0 -136
- data/lib/generators/blacklight_advanced_search/assets_generator.rb +0 -53
- data/lib/generators/blacklight_advanced_search/templates/advanced_controller.rb +0 -56
- data/lib/generators/blacklight_advanced_search/templates/saved_searches_controller.rb +0 -6
- data/lib/generators/blacklight_advanced_search/templates/search_history_controller.rb +0 -6
- data/solr/sample_solr_documents.yml +0 -2692
- data/spec/helpers/advanced_helper_spec.rb +0 -13
- data/spec/lib/blacklight_advanced_search/render_constraints_override_spec.rb +0 -39
- data/spec/lib/filter_parser_spec.rb +0 -22
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
This is an advanced search plugin for Blacklight ( http://www.projectblacklight.org ).
|
1
|
+
This is an advanced search plugin for Blacklight ( http://www.projectblacklight.org ).
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/blacklight_advanced_search.svg)](http://badge.fury.io/rb/blacklight_advanced_search) [![Build Status](https://travis-ci.org/projectblacklight/blacklight_advanced_search.svg)](https://travis-ci.org/projectblacklight/blacklight_advanced_search)
|
4
4
|
|
@@ -14,15 +14,15 @@ work with which versions of `blacklight`. Some notes:
|
|
14
14
|
facet selections, from the advanced form. If you'd like to keep old-style possibly
|
15
15
|
bookmarked URLs working, by redirecting to new format, add this to your
|
16
16
|
`CatalogController`:
|
17
|
-
|
17
|
+
|
18
18
|
before_filter BlacklightAdvancedSearch::RedirectLegacyParamsFilter, :only => :index
|
19
19
|
|
20
|
-
* version 2.2 of `blacklight_advanced_search` should work with `blacklight` 4.x.
|
20
|
+
* version 2.2 of `blacklight_advanced_search` should work with `blacklight` 4.x.
|
21
21
|
* versions `1.2.*` of Advanced Search plugin can work with blacklight 3.2.2 through latest 3.2.x
|
22
|
-
* 1.2.0 was an aborted version, don't use it, if you did, re-do your configuration according to current instructions and delete any local ./app/controllers/advanced_controller.rb file.
|
22
|
+
* 1.2.0 was an aborted version, don't use it, if you did, re-do your configuration according to current instructions and delete any local ./app/controllers/advanced_controller.rb file.
|
23
23
|
* advanced search 1.1.x versions will work with Blacklights 3.0.x through 3.1.x
|
24
|
-
* advanced search plugin latest 0.X.X version will work with Blacklight 2.9/Rails2.
|
25
|
-
* Older tagged versions of Advanced Search may work with even older BL.
|
24
|
+
* advanced search plugin latest 0.X.X version will work with Blacklight 2.9/Rails2.
|
25
|
+
* Older tagged versions of Advanced Search may work with even older BL.
|
26
26
|
|
27
27
|
## Installation
|
28
28
|
|
@@ -37,24 +37,24 @@ then run 'bundle install'. Then run:
|
|
37
37
|
rails generate blacklight_advanced_search
|
38
38
|
|
39
39
|
* The 'generate' command will install 'require' statements for the plugin's assets into your application's application.js/application.css asset pipeline files
|
40
|
-
* And it can optionally install a localized search form with a link to advanced search. If you've already localized your search form you'll want to do this manually instead.
|
40
|
+
* And it can optionally install a localized search form with a link to advanced search. If you've already localized your search form you'll want to do this manually instead.
|
41
41
|
|
42
|
-
You may want turn to enable AND/OR/NOT parsing even in ordinary search, this is not on by default. See "Expression parsing in ordinary search" below.
|
42
|
+
You may want turn to enable AND/OR/NOT parsing even in ordinary search, this is not on by default. See "Expression parsing in ordinary search" below.
|
43
43
|
|
44
44
|
## Accessing
|
45
|
-
|
45
|
+
|
46
46
|
The advanced search form will be available in your app at /advanced, and in your app using
|
47
|
-
routing helper `advanced_search_path`.
|
47
|
+
routing helper `advanced_search_path`.
|
48
48
|
|
49
49
|
advanced_search_path
|
50
|
-
|
50
|
+
|
51
51
|
You can also send the advanced search form url parameters representing a search, to have the form add on additional 'advanced' criteria to the search. For example:
|
52
52
|
|
53
53
|
advanced_search_path( params )
|
54
|
-
|
55
|
-
By default there won't be any links in your application to the search form. If you've heavily customized your app, you can put them wherever you want as above.
|
56
54
|
|
57
|
-
|
55
|
+
By default there won't be any links in your application to the search form. If you've heavily customized your app, you can put them wherever you want as above.
|
56
|
+
|
57
|
+
However, especially if your app isn't much customized, the optional installer can write a localized Blacklight search form into your application with a 'more options' link to advanced. You may need to adjust your styles to make room for the new link, depending on what you've done with your app.
|
58
58
|
|
59
59
|
|
60
60
|
## Configuration
|
@@ -68,7 +68,7 @@ Turn this feature on by adding to your SearchBuilder definition:
|
|
68
68
|
|
69
69
|
self.default_processor_chain << :add_advanced_parse_q_to_solr
|
70
70
|
|
71
|
-
This will intercept queries entered in ordinary Blacklight search interface, and parse them for AND/OR/NOT (and parens), producing appropriate Solr query. This allows single-field boolean expressions to be entered in ordinary search, providing a consistent experience with advanced search.
|
71
|
+
This will intercept queries entered in ordinary Blacklight search interface, and parse them for AND/OR/NOT (and parens), producing appropriate Solr query. This allows single-field boolean expressions to be entered in ordinary search, providing a consistent experience with advanced search.
|
72
72
|
|
73
73
|
Individual blacklight 'search fields' can have advanced parsing turned off:
|
74
74
|
|
@@ -78,39 +78,39 @@ Individual blacklight 'search fields' can have advanced parsing turned off:
|
|
78
78
|
end
|
79
79
|
|
80
80
|
|
81
|
-
When this feature is turned on, queries that don't have any special operators (eg: AND, OR, NOT, parens) will still be passed to Solr much the same as they were before. But queries with special operators will have appropriate Solr queries generated for them, usually including nested "_query_" elements, to have the same meaning they would in advanced search. If a user enters something that is a syntax error for parsed search (for instance an unclosed phrase quote or paren), the logic will rescue from the parse erorr by running the exact user entered query direct to solr without advanced parsing.
|
81
|
+
When this feature is turned on, queries that don't have any special operators (eg: AND, OR, NOT, parens) will still be passed to Solr much the same as they were before. But queries with special operators will have appropriate Solr queries generated for them, usually including nested "_query_" elements, to have the same meaning they would in advanced search. If a user enters something that is a syntax error for parsed search (for instance an unclosed phrase quote or paren), the logic will rescue from the parse erorr by running the exact user entered query direct to solr without advanced parsing.
|
82
82
|
|
83
83
|
Due to limitations of the logic, sometimes these generated Solr queries may not really be as simple as they could be, they may include a *single* nested _query_, which really doens't need to be a nested query at all, although it will still work fine.
|
84
84
|
|
85
|
-
If there'a a parse error trying to parse as boolean expression, it'll give up and pass the query on through same as it would without ParseBasicQ.
|
85
|
+
If there'a a parse error trying to parse as boolean expression, it'll give up and pass the query on through same as it would without ParseBasicQ.
|
86
86
|
|
87
87
|
### Search fields
|
88
88
|
|
89
|
-
Your main blacklight search fields are generally defined in CatalogController blacklight_config using `add_search_field`. They are all by default used in advanced search.
|
89
|
+
Your main blacklight search fields are generally defined in CatalogController blacklight_config using `add_search_field`. They are all by default used in advanced search.
|
90
90
|
|
91
91
|
If there are particular search fields in your main blacklight config you want excluded from the advanced search form, you can set ":include_in_advanced_search => false"
|
92
92
|
|
93
93
|
config.add_search_field("isbn") do |field|
|
94
94
|
field.include_in_advanced_search = false
|
95
|
-
field.solr_parameters = { :qf => "isbn_t" }
|
96
|
-
end
|
95
|
+
field.solr_parameters = { :qf => "isbn_t" }
|
96
|
+
end
|
97
97
|
|
98
98
|
If you want search fields ONLY available in advanced search, you can suppress them from ordinary search:
|
99
99
|
|
100
100
|
config.add_search_field("publisher") do |field|
|
101
101
|
field.include_in_simple_select = false
|
102
|
-
field.solr_parameters = { :qf => "publisher_t" }
|
102
|
+
field.solr_parameters = { :qf => "publisher_t" }
|
103
103
|
end
|
104
104
|
|
105
105
|
All advanced search fields must share the same Solr request handler (":qt"). As such, search fields that use a custom ":qt" parameter may not be re-used by the advanced search plugin. However, you may use a separate Solr request handler than the Blacklight default. If you would like the advanced search to use a different Solr request handler than your app's default, set:
|
106
|
-
|
107
|
-
config.advanced_search = {
|
106
|
+
|
107
|
+
config.advanced_search = {
|
108
108
|
:qt => 'advanced'
|
109
109
|
}
|
110
|
-
|
111
|
-
If you use a separate Solr request handler for advanced search, you must supply a completely separate list of search fields for the advanced search form, just define them with `:include_in_advanced_search => true` and `:include_in_simple_search => false` as above.
|
112
110
|
|
113
|
-
|
111
|
+
If you use a separate Solr request handler for advanced search, you must supply a completely separate list of search fields for the advanced search form, just define them with `:include_in_advanced_search => true` and `:include_in_simple_search => false` as above.
|
112
|
+
|
113
|
+
Additionally, to make your advanced search solr requests more concise, you are strongly encouraged to take advantage of the :local_solr_parameters option in your search field definition to use a solr parameter substitution with $variables.
|
114
114
|
|
115
115
|
configure_blacklight do |config|
|
116
116
|
config.add_search_field('author') do |field|
|
@@ -145,10 +145,9 @@ Within your solrconfig.xml you may then provide the appropriate custom configura
|
|
145
145
|
</lst>
|
146
146
|
</requestHandler>
|
147
147
|
|
148
|
-
|
149
148
|
### Facets on advanced search form
|
150
149
|
|
151
|
-
By default, the advanced search form will show as limits whatever facets are configured as default in your Solr request handler. To have the advanced search form request specific facets and/or specific facet parameters, you can set config[:form_solr_parameters].
|
150
|
+
By default, the advanced search form will show as limits whatever facets are configured as default in your Solr request handler. To have the advanced search form request specific facets and/or specific facet parameters, you can set config[:form_solr_parameters].
|
152
151
|
|
153
152
|
config.advanced_search = {
|
154
153
|
:form_solr_parameters => {
|
@@ -158,22 +157,11 @@ By default, the advanced search form will show as limits whatever facets are con
|
|
158
157
|
}
|
159
158
|
}
|
160
159
|
|
161
|
-
Multiply selected advanced search form facets are combined with `or` (ie `any` or `union`).
|
160
|
+
Multiply selected advanced search form facets are combined with `or` (ie `any` or `union`).
|
162
161
|
|
163
162
|
The default advanced search form facet display is very much like Blacklight's
|
164
163
|
sidebar facets (and uses some code straight from BL to render), but with checkboxes
|
165
|
-
next to each value.
|
166
|
-
|
167
|
-
(IN PROGRESS) An alternate view using a multi-element HTML `select` is available, and can also
|
168
|
-
be combined with [chosen.js](http://harvesthq.github.io/chosen/) for a fancy type-ahead style of UI.
|
169
|
-
This can be especially useful if you want to offer many facet values at once on
|
170
|
-
the form (beware, they are all still loaded in HTML, so this is probably good for
|
171
|
-
at most hundreds, not thousands.)
|
172
|
-
|
173
|
-
config.advanced_search = {
|
174
|
-
# ...
|
175
|
-
:form_facet_partial => "advanced_search_facets_as_select"
|
176
|
-
}
|
164
|
+
next to each value.
|
177
165
|
|
178
166
|
### Advanced Search Config Options
|
179
167
|
|
@@ -181,48 +169,46 @@ Complete list of keys that can be supplied inside your configure_blacklight `adv
|
|
181
169
|
|
182
170
|
* :qt
|
183
171
|
* Solr request handler to use for any search that includes advanced search criteria. Defaults to what the application has set as blacklight_config.default_solr_params[:qt]
|
184
|
-
* :
|
185
|
-
*
|
186
|
-
* :form_solr_paramters
|
187
|
-
* A hash of solr parameters which will be included in Solr request sent before display of advanced search form. Can be used to set facet parameters for advanced search form display.
|
172
|
+
* :form_solr_parameters
|
173
|
+
* A hash of solr parameters which will be included in Solr request sent before display of advanced search form. Can be used to set facet parameters for advanced search form display.
|
188
174
|
* :query_parser
|
189
|
-
* advanced searches are translated to solr nested queries, where the inner queries are of a dismax-type.
|
190
|
-
By default, they are actually specifically 'dismax', but you can set :query_parser to 'edismax' instead.
|
175
|
+
* advanced searches are translated to solr nested queries, where the inner queries are of a dismax-type.
|
176
|
+
By default, they are actually specifically 'dismax', but you can set :query_parser to 'edismax' instead.
|
191
177
|
This may make additional features available like * wildcards in advanced searches; but it may also
|
192
178
|
cause some user query elements to be interpreted as operators for edismax when they
|
193
|
-
were intended as literals. Somewhat experimental. See Github issues #11 and #14.
|
179
|
+
were intended as literals. Somewhat experimental. See Github issues #11 and #14.
|
194
180
|
|
195
181
|
## Customizing the advanced search form
|
196
182
|
|
197
183
|
Most of the labels on the advanced search form are [provided via Rails i18n](./config/locales), and can
|
198
|
-
be customized in a local app i18n file.
|
184
|
+
be customized in a local app i18n file.
|
199
185
|
|
200
|
-
Additionally, you can override the templates from this gem used to display the form.
|
186
|
+
Additionally, you can override the templates from this gem used to display the form.
|
201
187
|
We've tried to break it up into partials at the right granularity for over-riding
|
202
188
|
in likely ways. For one example, see the wiki page on [Adding a range limit to the advanced search form](https://github.com/projectblacklight/blacklight_advanced_search/wiki/Adding-a-range-limit-to-the-advanced-search-form).
|
203
189
|
|
204
190
|
|
205
191
|
## Translation to Solr Query, technical details
|
206
192
|
|
207
|
-
The code for mapping a user-entered query to a Solr query is called "nesting_parsing", and maps to a 'lucene' query parser query, with nested 'dismax' query parser queries.
|
193
|
+
The code for mapping a user-entered query to a Solr query is called "nesting_parsing", and maps to a 'lucene' query parser query, with nested 'dismax' query parser queries.
|
208
194
|
|
209
|
-
Some technical details can be found in the nesting_parsing README: [https://github.com/projectblacklight/blacklight_advanced_search/tree/
|
195
|
+
Some technical details can be found in the nesting_parsing README: [https://github.com/projectblacklight/blacklight_advanced_search/tree/main/lib/parsing_nesting]
|
210
196
|
|
211
197
|
You may also find the rspecs for parsing a user-entered query and converting it to Solr illumnating:
|
212
198
|
|
213
|
-
1. Converting user-entered query to Solr: [https://github.com/projectblacklight/blacklight_advanced_search/blob/
|
214
|
-
2. Parsing user-entered query to internal syntax tree: [https://github.com/projectblacklight/blacklight_advanced_search/blob/
|
215
|
-
|
199
|
+
1. Converting user-entered query to Solr: [https://github.com/projectblacklight/blacklight_advanced_search/blob/main/spec/parsing_nesting/to_solr_spec.rb]
|
200
|
+
2. Parsing user-entered query to internal syntax tree: [https://github.com/projectblacklight/blacklight_advanced_search/blob/main/spec/parsing_nesting/build_tree_spec.rb]
|
201
|
+
|
216
202
|
## Running tests
|
217
203
|
|
218
204
|
|
219
205
|
(Limited) test coverage is provided with rspec, run all tests (and start the jetty instance) by running:
|
220
|
-
rake ci
|
206
|
+
rake ci
|
207
|
+
|
208
|
+
from the blacklight_advanced_search directory. Note: you may need to `bundle install` first.
|
221
209
|
|
222
|
-
from the blacklight_advanced_search directory. Note: you may need to `bundle install` first.
|
223
210
|
|
224
|
-
|
225
211
|
## To Do
|
226
212
|
|
227
|
-
* Alphabetical sorting of facet values returned by solr in count order (perhaps with limit).
|
228
|
-
* Parse for fielded search too like << title:"some title" >>. 'field:' that doesn't match an actual known field should be passed through same as now, while recognized fields should generate nested queries tied to those blacklight search types.
|
213
|
+
* Alphabetical sorting of facet values returned by solr in count order (perhaps with limit).
|
214
|
+
* Parse for fielded search too like << title:"some title" >>. 'field:' that doesn't match an actual known field should be passed through same as now, while recognized fields should generate nested queries tied to those blacklight search types.
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bundler/setup'
|
2
4
|
Bundler::GemHelper.install_tasks
|
3
5
|
|
@@ -6,8 +8,6 @@ require 'rubocop/rake_task'
|
|
6
8
|
require 'rspec/core/rake_task'
|
7
9
|
require 'engine_cart/rake_task'
|
8
10
|
|
9
|
-
EngineCart.fingerprint_proc = EngineCart.rails_fingerprint_proc
|
10
|
-
|
11
11
|
task :default => :ci
|
12
12
|
|
13
13
|
desc "Run specs"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
8.0.0.alpha2
|
@@ -9,24 +9,23 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ["blacklight-development@googlegroups.com"]
|
10
10
|
s.homepage = "http://projectblacklight.org/"
|
11
11
|
s.summary = "Blacklight Advanced Search plugin"
|
12
|
-
s.license = "Apache
|
13
|
-
|
14
|
-
s.rubyforge_project = "blacklight"
|
12
|
+
s.license = "Apache-2.0"
|
15
13
|
|
16
14
|
s.files = `git ls-files`.split("\n")
|
17
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
17
|
s.require_paths = ["lib"]
|
20
18
|
|
21
|
-
s.add_dependency 'blacklight', '
|
19
|
+
s.add_dependency 'blacklight', '>= 7.15', '< 9'
|
22
20
|
s.add_dependency "parslet"
|
23
21
|
|
24
22
|
s.add_development_dependency "rails"
|
25
|
-
s.add_development_dependency "rspec-rails", "~>
|
23
|
+
s.add_development_dependency "rspec-rails", "~> 5.0"
|
26
24
|
s.add_development_dependency "capybara"
|
27
|
-
s.add_development_dependency 'solr_wrapper'
|
28
|
-
s.add_development_dependency 'engine_cart', "~> 0
|
25
|
+
s.add_development_dependency 'solr_wrapper'
|
26
|
+
s.add_development_dependency 'engine_cart', "~> 2.0"
|
29
27
|
s.add_development_dependency 'rubocop'
|
28
|
+
s.add_development_dependency 'rubocop-rails'
|
30
29
|
s.add_development_dependency 'rubocop-rspec'
|
31
30
|
s.add_development_dependency 'rsolr'
|
32
31
|
end
|
data/config/routes.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'parsing_nesting/tree'
|
2
|
+
|
1
3
|
module BlacklightAdvancedSearch
|
2
4
|
# Can extract query elements from rails #params query params, and then parse
|
3
5
|
# them and convert them into a solr query with #to_solr
|
@@ -5,66 +7,50 @@ module BlacklightAdvancedSearch
|
|
5
7
|
# #keyword_queries and #filters, which just return extracted elements of query
|
6
8
|
# params, may also be useful in display etc.
|
7
9
|
class QueryParser
|
8
|
-
|
9
|
-
include FilterParser
|
10
|
-
attr_reader :config, :params
|
10
|
+
attr_reader :config, :search_state
|
11
11
|
|
12
|
-
def initialize(
|
13
|
-
@
|
12
|
+
def initialize(search_state, config)
|
13
|
+
@search_state = search_state
|
14
14
|
@config = config
|
15
15
|
end
|
16
16
|
|
17
17
|
def to_solr
|
18
18
|
@to_solr ||= begin
|
19
19
|
{
|
20
|
-
:
|
21
|
-
:fq => generate_solr_fq
|
20
|
+
q: process_query(config)
|
22
21
|
}
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
# Returns "AND" or "OR", how #keyword_queries will be combined
|
27
26
|
def keyword_op
|
28
|
-
|
27
|
+
op = search_state.params[:op]&.to_sym || :must
|
28
|
+
|
29
|
+
if op == :should
|
30
|
+
'OR'
|
31
|
+
else
|
32
|
+
'AND'
|
33
|
+
end
|
29
34
|
end
|
30
35
|
|
31
|
-
# extracts advanced-type keyword query elements from query params,
|
32
|
-
# returns as a kash of field => query.
|
33
|
-
# see also keyword_op
|
34
36
|
def keyword_queries
|
35
|
-
|
36
|
-
@keyword_queries = {}
|
37
|
-
|
38
|
-
return @keyword_queries unless @params[:search_field] == ::AdvancedController.blacklight_config.advanced_search[:url_key]
|
39
|
-
|
40
|
-
config.search_fields.each do |key, _field_def|
|
41
|
-
unless @params[key.to_sym].blank?
|
42
|
-
@keyword_queries[key] = @params[key.to_sym]
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
@keyword_queries
|
37
|
+
search_state.clause_params.values.select { |clause| clause[:query].present? }
|
47
38
|
end
|
48
39
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
@params[:f_inclusive].each_pair do |field, value_array|
|
56
|
-
@filters[field] ||= value_array.dup
|
57
|
-
end
|
40
|
+
def process_query(config)
|
41
|
+
queries = keyword_queries.map do |clause|
|
42
|
+
field = clause[:field]
|
43
|
+
query = clause[:query]
|
44
|
+
|
45
|
+
ParsingNesting::Tree.parse(query, config.advanced_search[:query_parser]).to_query(local_param_hash(field, config))
|
58
46
|
end
|
59
|
-
|
47
|
+
queries.join(" #{keyword_op} ")
|
60
48
|
end
|
61
49
|
|
62
|
-
def
|
63
|
-
|
64
|
-
end
|
50
|
+
def local_param_hash(key, config)
|
51
|
+
field_def = config.search_fields[key] || {}
|
65
52
|
|
66
|
-
|
67
|
-
filters.empty? && keyword_queries.empty?
|
53
|
+
(field_def[:solr_adv_parameters] || field_def[:solr_parameters] || {}).merge(field_def[:solr_local_parameters] || {})
|
68
54
|
end
|
69
55
|
end
|
70
56
|
end
|
@@ -2,36 +2,37 @@ require 'parslet'
|
|
2
2
|
require 'parsing_nesting/tree'
|
3
3
|
module BlacklightAdvancedSearch
|
4
4
|
module AdvancedSearchBuilder
|
5
|
-
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
self.default_processor_chain += [
|
9
|
+
:facets_for_advanced_search_form
|
10
|
+
]
|
11
|
+
end
|
6
12
|
|
7
13
|
def is_advanced_search?
|
8
|
-
|
14
|
+
search_state.clause_params.any?
|
9
15
|
end
|
10
16
|
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
# adds a 'q' and 'fq's based on advanced search form input.
|
15
|
-
def add_advanced_search_to_solr(solr_parameters)
|
17
|
+
# Override the upstream adv. search implementation to use our own
|
18
|
+
def add_adv_search_clauses(solr_parameters)
|
19
|
+
return unless is_advanced_search?
|
16
20
|
# If we've got the hint that we're doing an 'advanced' search, then
|
17
21
|
# map that to solr #q, over-riding whatever some other logic may have set, yeah.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
unless advanced_query.keyword_queries.empty?
|
26
|
-
# force :qt if set, fine if it's nil, we'll use whatever CatalogController
|
27
|
-
# ordinarily uses.
|
28
|
-
solr_parameters[:qt] = self.blacklight_config.advanced_search[:qt]
|
29
|
-
solr_parameters[:defType] = "lucene"
|
30
|
-
end
|
31
|
-
|
22
|
+
advanced_query = BlacklightAdvancedSearch::QueryParser.new(search_state, blacklight_config)
|
23
|
+
BlacklightAdvancedSearch.deep_merge!(solr_parameters, advanced_query.to_solr)
|
24
|
+
unless advanced_query.keyword_queries.empty?
|
25
|
+
# force :qt if set, fine if it's nil, we'll use whatever CatalogController
|
26
|
+
# ordinarily uses.
|
27
|
+
solr_parameters[:qt] = self.blacklight_config.advanced_search[:qt]
|
28
|
+
solr_parameters[:defType] = "lucene"
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
32
|
+
# this method is left for backwards compatibility.
|
33
|
+
def add_advanced_search_to_solr(solr_parameters)
|
34
|
+
end
|
35
|
+
|
35
36
|
# Different versions of Parslet raise different exception classes,
|
36
37
|
# need to figure out which one exists to rescue
|
37
38
|
PARSLET_FAILED_EXCEPTIONS = if defined? Parslet::UnconsumedInput
|
@@ -50,8 +51,8 @@ module BlacklightAdvancedSearch
|
|
50
51
|
def add_advanced_parse_q_to_solr(solr_parameters)
|
51
52
|
return if blacklight_params[:q].blank? || !blacklight_params[:q].respond_to?(:to_str)
|
52
53
|
|
53
|
-
field_def =
|
54
|
-
default_search_field
|
54
|
+
field_def = blacklight_config.search_fields[blacklight_params[:search_field]] ||
|
55
|
+
blacklight_config.default_search_field
|
55
56
|
|
56
57
|
# If the individual field has advanced_parse_q suppressed, punt
|
57
58
|
return if field_def[:advanced_parse] == false
|
@@ -75,12 +76,14 @@ module BlacklightAdvancedSearch
|
|
75
76
|
end
|
76
77
|
|
77
78
|
# A Solr param filter that is NOT included by default in the chain,
|
78
|
-
# but is appended
|
79
|
+
# but is appended for advanced searches, to do a search
|
79
80
|
# for facets _ignoring_ the current query, we want the facets
|
80
81
|
# as if the current query weren't there.
|
81
82
|
#
|
82
83
|
# Also adds any solr params set in blacklight_config.advanced_search[:form_solr_parameters]
|
83
84
|
def facets_for_advanced_search_form(solr_p)
|
85
|
+
return unless search_state.controller&.action_name == "advanced_search"
|
86
|
+
|
84
87
|
# ensure empty query is all records, to fetch available facets on entire corpus
|
85
88
|
solr_p["q"] = '{!lucene}*:*'
|
86
89
|
# explicitly use lucene defType since we are passing a lucene query above (and appears to be required for solr 7)
|
@@ -1,23 +1,22 @@
|
|
1
|
-
require 'blacklight_advanced_search/parsing_nesting_parser'
|
2
|
-
|
3
1
|
# This module gets included into CatalogController, or another SearchHelper
|
4
|
-
# includer, to
|
2
|
+
# includer, to override
|
5
3
|
module BlacklightAdvancedSearch::Controller
|
6
|
-
|
4
|
+
if Blacklight::VERSION < '7.27'
|
5
|
+
# before Blacklight 7.27, the provided search service didn't receive this controller
|
6
|
+
def advanced_search
|
7
|
+
(@response, _deprecated_document_list) = blacklight_advanced_search_form_search_service.search_results
|
8
|
+
end
|
7
9
|
|
8
|
-
|
9
|
-
# Display advanced search constraints properly
|
10
|
-
helper BlacklightAdvancedSearch::RenderConstraintsOverride
|
11
|
-
helper BlacklightAdvancedSearch::CatalogHelperOverride
|
12
|
-
helper_method :is_advanced_search?, :advanced_query
|
13
|
-
end
|
10
|
+
private
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
def blacklight_advanced_search_form_search_service
|
13
|
+
form_search_state = search_state_class.new(blacklight_advanced_search_form_params, blacklight_config, self)
|
14
|
+
|
15
|
+
search_service_class.new(config: blacklight_config, search_state: form_search_state, user_params: form_search_state.to_h, **search_service_context)
|
16
|
+
end
|
19
17
|
|
20
|
-
|
21
|
-
|
18
|
+
def blacklight_advanced_search_form_params
|
19
|
+
{}
|
20
|
+
end
|
22
21
|
end
|
23
22
|
end
|
@@ -1,18 +1,35 @@
|
|
1
1
|
# Returns a lambda that you can use with a before_filter in your
|
2
2
|
# CatalogController to catch and redirect query params using the old
|
3
|
-
# style
|
3
|
+
# style
|
4
4
|
#
|
5
5
|
# This can be used to keep any old bookmarked URLs still working.
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# before_action BlacklightAdvancedSearch::RedirectLegacyParamsFilter, :only => :index
|
8
8
|
#
|
9
9
|
module BlacklightAdvancedSearch
|
10
10
|
class RedirectLegacyParamsFilter
|
11
11
|
def self.before(controller)
|
12
12
|
params = controller.send(:params)
|
13
|
+
legacy_converted = false
|
13
14
|
|
15
|
+
# This was used prior to blacklight_advanceod_search 8
|
16
|
+
i = 0
|
17
|
+
controller.blacklight_config.search_fields.each do |_key, field|
|
18
|
+
next unless params[field.key].present?
|
19
|
+
legacy_converted = true
|
20
|
+
|
21
|
+
params[:clause] ||= {}
|
22
|
+
params[:clause][i] = {
|
23
|
+
field: field.key,
|
24
|
+
query: params[field.key]
|
25
|
+
}
|
26
|
+
i += 1
|
27
|
+
|
28
|
+
params.delete(field.key)
|
29
|
+
end
|
30
|
+
|
31
|
+
# This was used prior to blacklight_advanced_search 5.0.
|
14
32
|
if params[:f_inclusive] && params[:f_inclusive].respond_to?(:each_pair)
|
15
|
-
legacy_converted = false
|
16
33
|
|
17
34
|
params[:f_inclusive].each_pair do |field, value|
|
18
35
|
next unless value.is_a? Hash
|
@@ -20,11 +37,11 @@ module BlacklightAdvancedSearch
|
|
20
37
|
legacy_converted = true
|
21
38
|
params[:f_inclusive][field] = value.keys
|
22
39
|
end
|
40
|
+
end
|
23
41
|
|
24
|
-
|
25
|
-
|
26
|
-
end
|
42
|
+
if legacy_converted
|
43
|
+
controller.send(:redirect_to, params.to_unsafe_h, :status => :moved_permanently)
|
27
44
|
end
|
28
45
|
end
|
29
46
|
end
|
30
|
-
|
47
|
+
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
module BlacklightAdvancedSearch
|
2
2
|
autoload :AdvancedSearchBuilder, 'blacklight_advanced_search/advanced_search_builder'
|
3
3
|
autoload :Controller, 'blacklight_advanced_search/controller'
|
4
|
-
autoload :RenderConstraintsOverride, 'blacklight_advanced_search/render_constraints_override'
|
5
|
-
autoload :CatalogHelperOverride, 'blacklight_advanced_search/catalog_helper_override'
|
6
4
|
autoload :QueryParser, 'blacklight_advanced_search/advanced_query_parser'
|
7
|
-
autoload :ParsingNestingParser, 'blacklight_advanced_search/parsing_nesting_parser'
|
8
|
-
autoload :FilterParser, 'blacklight_advanced_search/filter_parser'
|
9
5
|
autoload :RedirectLegacyParamsFilter, 'blacklight_advanced_search/redirect_legacy_params_filter'
|
10
6
|
|
11
7
|
require 'blacklight_advanced_search/version'
|