Overview
Blacklight generates app/models/search_builder.rb
into your application. It defaults to including Blacklight::Solr::SearchBuilderBehavior
which are functions that allow Blacklight to talk to Solr (vs another search engine). Samvera generates include Hydra::AccessControlsEnforcement
for filtering
searches by access (groups & users). Finally Hyrax generates include Hyrax::SearchFilters
which overrides the Samvera filters and allows users with the admin role to see all documents.
Hyrax then sets the blacklight_config.config.search_builder_class = Hyrax::CatalogSearchBuilder
in the catalog controller. This enables the public search to not show works that are suppressed (in workflow) and to find a work if an attached file matches the search query.
Search Builders
Building searches is a core component of any Blacklight app. The app/search_builders/ directory contains our Search Builders, originally so-named because the class design followed a Builder pattern. Builder setter methods return the object itself when invoked, so that invocations can be chained, like:
builder = Blacklight::SearchBuilder.new(processor_chain, scope)
.rows(20)
.page(3)
.with(q: 'Abraham Lincoln')
However, at this level, many if not most of the additional methods do not follow this pattern. So these builders create searches in the general sense of the name, not by strictly following the Builder pattern. Refer to the Blacklight::SearchBuilder
class if you want to be certain of whether a method can be chained. That leads to the next topic…
Ancestry
Most of the SearchBuilders have ::SearchBuilder
as a parent or ancestor. ::SearchBuilder
does not exist in any repo: it is generated by Blacklight and modified by CurationConcerns. Others descend from Blacklight::SearchBuilder
, or various other relatives.
::SearchBuilder
The generated parent class SearchBuilder
descends from Blacklight::SearchBuilder
.
As modified by the Hyrax installer, it includes additional modules and overrides. So if your SearchBuilder has ::SearchBuilder
as a parent class, you are getting:
- Blacklight::SearchBuilder grandparent class
- Blacklight::Solr::SearchBuilderBehavior associated methods
- Hydra::AccessControlsEnforcement module
- Blacklight::AccessControls::Enforcement ancestor of
Hydra::AccessControlsEnforcement
- Blacklight::AccessControls::Enforcement ancestor of
- CurationConcerns::SearchFilters module that itself includes:
- BlacklightAdvancedSearch::AdvancedSearchBuilder more magic for compound Boolean queries
- CurationConcerns::FilterByType Collection vs. Work filtering, specifically the
filter_models
method
This is not a comprehensive list, but it is sufficient to trace some of the complexity of interaction between various layers.
Development: AKA Doing Something Useful
Important note: the default_processor_chain
defined by Blacklight::Solr::SearchBuilderBehavior
provides a way to extend functionality, but also many possible points of override (namely method names). When you need to do something novel and additional, adding to the chain is completely reasonable. For example:
module MySearchBuilder
extend ActiveSupport::Concern
included do
self.default_processor_chain += [:special_filter]
end
def special_filter(solr_parameters)
solr_parameters[:fq] << "{!field f=some_field_ssim}#{...}"
end
end
But to the extent that you are overriding (or undoing) something already done, Hyrax::FileSetSearchBuilder
is a better example:
module Hyrax
class FileSetSearchBuilder < ::SearchBuilder
include Hyrax::SingleResult
# This overrides the models in FilterByType
def models
[::FileSet]
end
end
end
There is no point having the other filter_models
methods apply :fq
s that we then try to undo or overwrite. In general, directly overwriting the whole default_processor_chain
or solr parameters like :fq
is less flexible than appending constraints sufficient for your use case. In particular, you might find that you have overwritten components that implement access controls, thereby making your SearchBuilder less useful and less secure. When in doubt, examine the actual solr queries produced.
More Information
Legacy
Blacklight Search Results, hydra-head version 6.0.0
Gated Discovery Filter Search Results, permissions-based, hydra-head versions 6.4.0 and 7.2.2