Class: Search
- Inherits:
-
Struct
- Object
- Struct
- Search
- Defined in:
- backend/app/model/search.rb,
frontend/app/models/search.rb,
public/app/models/search.rb
Constant Summary collapse
- @@BooleanOpts =
[]
- @@SortOpts =
we create all the possible sort options here, then refine them according to what’s being sorted
{}
Instance Attribute Summary collapse
-
#dates_searched ⇒ Object
Returns the value of attribute dates_searched.
-
#dates_within ⇒ Object
Returns the value of attribute dates_within.
-
#field ⇒ Object
Returns the value of attribute field.
-
#filter_fields ⇒ Object
Returns the value of attribute filter_fields.
-
#filter_from_year ⇒ Object
Returns the value of attribute filter_from_year.
-
#filter_q ⇒ Object
Returns the value of attribute filter_q.
-
#filter_to_year ⇒ Object
Returns the value of attribute filter_to_year.
-
#filter_values ⇒ Object
Returns the value of attribute filter_values.
-
#from_year ⇒ Object
Returns the value of attribute from_year.
-
#limit ⇒ Object
Returns the value of attribute limit.
-
#op ⇒ Object
Returns the value of attribute op.
-
#q ⇒ Object
Returns the value of attribute q.
-
#recordtypes ⇒ Object
Returns the value of attribute recordtypes.
-
#search_statement ⇒ Object
Returns the value of attribute search_statement.
-
#sort ⇒ Object
Returns the value of attribute sort.
-
#text_within ⇒ Object
Returns the value of attribute text_within.
-
#to_year ⇒ Object
Returns the value of attribute to_year.
Class Method Summary collapse
-
.all(repo_id, criteria, context_criteria = {}) ⇒ Object
:context_criteria - added to criteria for building the query, but hidden from user :sorting - ignore repo preferences and use provided sort for results (i.e. for typeaheads).
-
.for_type(repo_id, type, criteria) ⇒ Object
-
.get_boolean_opts ⇒ Object
-
.get_sort_opts ⇒ Object
-
.global(criteria, type) ⇒ Object
-
.record_type_counts(record_types, for_repo_uri = nil) ⇒ Object
-
.records_for_uris(uris, resolve = []) ⇒ Object
-
.search(params, repo_id) ⇒ Object
-
.search_csv(params, repo_id) ⇒ Object
Instance Method Summary collapse
-
#allow_dates? ⇒ Boolean
-
#filters_blank? ⇒ Boolean
-
#get_filter_q_arr(url = nil) ⇒ Object
-
#get_filter_q_params ⇒ Object
-
#has_query? ⇒ Boolean
-
#have_contents?(year_array) ⇒ Boolean
-
#initialize(params = {}) ⇒ Search
constructor
We take params either as a Hash or ActionController::Parameters object.
-
#search_dates_within? ⇒ Boolean
Constructor Details
#initialize(params = {}) ⇒ Search
We take params either as a Hash or ActionController::Parameters object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'public/app/models/search.rb', line 32 def initialize(params = {}) # Rails.logger.debug("Initializing: #{params}") %w(q op field from_year to_year filter_fields filter_values filter_q recordtypes ).each do |f| if params.is_a?(Hash) self[f.to_sym] = params[f.to_sym] || [] else self[f.to_sym] = params.fetch(f.to_sym, []) end end %w(limit filter_from_year filter_to_year).each do |f| if params.is_a?(Hash) self[f.to_sym] = params[f.to_sym] || '' else self[f.to_sym] = params.fetch(f.to_sym, '') end end self[:q].each_with_index do |q, i| self[:q][i] = '*' if q.blank? end self[:sort] = params.fetch('sort', nil) self[:dates_searched] = have_contents?(from_year) || have_contents?(to_year) self[:dates_within] = self[:text_within] = false end |
Instance Attribute Details
#dates_searched ⇒ Object
Returns the value of attribute dates_searched
1 2 3 |
# File 'public/app/models/search.rb', line 1 def dates_searched @dates_searched end |
#dates_within ⇒ Object
Returns the value of attribute dates_within
1 2 3 |
# File 'public/app/models/search.rb', line 1 def dates_within @dates_within end |
#field ⇒ Object
Returns the value of attribute field
1 2 3 |
# File 'public/app/models/search.rb', line 1 def field @field end |
#filter_fields ⇒ Object
Returns the value of attribute filter_fields
1 2 3 |
# File 'public/app/models/search.rb', line 1 def filter_fields @filter_fields end |
#filter_from_year ⇒ Object
Returns the value of attribute filter_from_year
1 2 3 |
# File 'public/app/models/search.rb', line 1 def filter_from_year @filter_from_year end |
#filter_q ⇒ Object
Returns the value of attribute filter_q
1 2 3 |
# File 'public/app/models/search.rb', line 1 def filter_q @filter_q end |
#filter_to_year ⇒ Object
Returns the value of attribute filter_to_year
1 2 3 |
# File 'public/app/models/search.rb', line 1 def filter_to_year @filter_to_year end |
#filter_values ⇒ Object
Returns the value of attribute filter_values
1 2 3 |
# File 'public/app/models/search.rb', line 1 def filter_values @filter_values end |
#from_year ⇒ Object
Returns the value of attribute from_year
1 2 3 |
# File 'public/app/models/search.rb', line 1 def from_year @from_year end |
#limit ⇒ Object
Returns the value of attribute limit
1 2 3 |
# File 'public/app/models/search.rb', line 1 def limit @limit end |
#op ⇒ Object
Returns the value of attribute op
1 2 3 |
# File 'public/app/models/search.rb', line 1 def op @op end |
#q ⇒ Object
Returns the value of attribute q
1 2 3 |
# File 'public/app/models/search.rb', line 1 def q @q end |
#recordtypes ⇒ Object
Returns the value of attribute recordtypes
1 2 3 |
# File 'public/app/models/search.rb', line 1 def recordtypes @recordtypes end |
#search_statement ⇒ Object
Returns the value of attribute search_statement
1 2 3 |
# File 'public/app/models/search.rb', line 1 def search_statement @search_statement end |
#sort ⇒ Object
Returns the value of attribute sort
1 2 3 |
# File 'public/app/models/search.rb', line 1 def sort @sort end |
#text_within ⇒ Object
Returns the value of attribute text_within
1 2 3 |
# File 'public/app/models/search.rb', line 1 def text_within @text_within end |
#to_year ⇒ Object
Returns the value of attribute to_year
1 2 3 |
# File 'public/app/models/search.rb', line 1 def to_year @to_year end |
Class Method Details
.all(repo_id, criteria, context_criteria = {}) ⇒ Object
:context_criteria - added to criteria for building the query, but hidden from user :sorting - ignore repo preferences and use provided sort for results (i.e. for typeaheads)
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'frontend/app/models/search.rb', line 14 def self.all(repo_id, criteria, context_criteria = {}) context_criteria.each do |k, v| if v.is_a? Array criteria[k] ||= [] criteria[k] += v else criteria[k] = v end end build_filters(criteria) criteria["page"] = 1 if not criteria.has_key?("page") criteria["sort"] ||= sort(criteria["type[]"] || (criteria["filter_term[]"] || []).collect { |term| ASUtils.json_parse(term)['primary_type'] }.compact) search_data = JSONModel::HTTP::get_json("/repositories/#{repo_id}/search", criteria) #If the criteria contains a 'blank_facet_query_fields' field, #we want to add a facet to filter on items WITHOUT an entry in the facet if (criteria.has_key?("blank_facet_query_fields")) blank_facet_query = "" criteria["blank_facet_query_fields"].each {|query_field| blank_facet_query = "-" + query_field + ":*" sub_criteria = criteria.clone if (sub_criteria.has_key?("q") && sub_criteria["q"] != blank_facet_query) sub_criteria["q"] = criteria["q"] + " AND " + blank_facet_query else sub_criteria["q"] = blank_facet_query end search_data_with_blank_facet = JSONModel::HTTP::get_json("/repositories/#{repo_id}/search", sub_criteria) if (!search_data["facets"]["facet_fields"].has_key?(query_field)) search_data["facets"]["facet_fields"][query_field] = ["none", search_data_with_blank_facet["total_hits"]] else search_data["facets"]["facet_fields"][query_field] << "none" search_data["facets"]["facet_fields"][query_field] << search_data_with_blank_facet["total_hits"] end } end SearchResultData.new(search_data, criteria, context_criteria) end |
.for_type(repo_id, type, criteria) ⇒ Object
6 7 8 9 10 |
# File 'frontend/app/models/search.rb', line 6 def self.for_type(repo_id, type, criteria) criteria['type[]'] = Array(type) Search.all(repo_id, criteria) end |
.get_boolean_opts ⇒ Object
5 6 7 8 9 10 11 12 |
# File 'public/app/models/search.rb', line 5 def Search.get_boolean_opts if @@BooleanOpts.empty? %w(AND OR NOT).each do |opt| @@BooleanOpts.push([ I18n.t("advanced_search.operator.#{opt}"), opt]) end end @@BooleanOpts end |
.get_sort_opts ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'public/app/models/search.rb', line 17 def Search.get_sort_opts if @@SortOpts.empty? @@SortOpts['relevance'] = [I18n.t('search_sorting.relevance'), ""] # the things we do for I18n! %w(title_sort year_sort identifier).each do |type| %w(asc desc).each do |dir| @@SortOpts["#{type}_#{dir}"] = [I18n.t('search_sorting.sorting', :type => I18n.t("search_sorting.#{type}"), :direction => I18n.t("search_sorting.#{dir}")), "#{type} #{dir}"] end end end @@SortOpts end |
.global(criteria, type) ⇒ Object
58 59 60 61 62 63 64 65 66 |
# File 'frontend/app/models/search.rb', line 58 def self.global(criteria, type) build_filters(criteria) criteria["page"] = 1 if not criteria.has_key?("page") search_data = JSONModel::HTTP::get_json("/search/#{type}", criteria) search_data[:type] = type SearchResultData.new(search_data, criteria) end |
.record_type_counts(record_types, for_repo_uri = nil) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'backend/app/model/search.rb', line 108 def self.record_type_counts(record_types, for_repo_uri = nil) show_suppressed = !RequestContext.get(:enforce_suppression) show_published_only = RequestContext.get(:current_username) === User.PUBLIC_USERNAME result = {} repos_of_interest = if for_repo_uri [for_repo_uri] else Repository.filter(:hidden => 0).select(:id).map do |row| repo_id = row[:id] JSONModel.JSONModel(:repository).uri_for(repo_id) end end repos_of_interest.each do |repo_uri| result[repo_uri] ||= {} record_types.each do |record_type| boolean_query = JSONModel.JSONModel(:boolean_query) .from_hash('op' => 'AND', 'subqueries' => [ JSONModel.JSONModel(:boolean_query).from_hash('op' => 'OR', 'subqueries' => [ JSONModel.JSONModel(:field_query) .from_hash('field' => 'used_within_repository', 'value' => repo_uri, 'literal' => true).to_hash, JSONModel.JSONModel(:field_query) .from_hash('field' => 'repository', 'value' => repo_uri, 'literal' => true).to_hash ]), JSONModel.JSONModel(:field_query) .from_hash('field' => 'types', 'value' => record_type, 'literal' => true).to_hash, JSONModel.JSONModel(:field_query) .from_hash('field' => 'published', 'value' => 'true', 'literal' => true).to_hash ]) query = Solr::Query.create_advanced_search(JSONModel.JSONModel(:advanced_query).from_hash('query' => boolean_query)) query.pagination(1, 1). show_suppressed(show_suppressed). show_published_only(show_published_only) hits = Solr.search(query) result[repo_uri][record_type] = hits['total_hits'] end end if for_repo_uri # We're just targeting a single repo result.values.first else result end end |
.records_for_uris(uris, resolve = []) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'backend/app/model/search.rb', line 76 def self.records_for_uris(uris, resolve = []) show_suppressed = !RequestContext.get(:enforce_suppression) show_published_only = RequestContext.get(:current_username) === User.PUBLIC_USERNAME boolean_query = JSONModel.JSONModel(:boolean_query) .from_hash('op' => 'OR', 'subqueries' => uris.map {|uri| field = uri.end_with?('#pui') ? 'id' : 'uri' JSONModel.JSONModel(:field_query) .from_hash('field' => field, 'value' => uri, 'literal' => true) .to_hash }) query = Solr::Query.create_advanced_search(JSONModel.JSONModel(:advanced_query).from_hash('query' => boolean_query)) query.pagination(1, uris.length). show_suppressed(show_suppressed). show_published_only(show_published_only) results = Solr.search(query) resolver = SearchResolver.new(resolve) resolver.resolve(results) # Keep the ordering that we were passed in our list of URIs results['results'].sort_by! {|result| uris.index(result['uri'])} results end |
.search(params, repo_id) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'backend/app/model/search.rb', line 5 def self.search(params, repo_id) show_suppressed = !RequestContext.get(:enforce_suppression) show_published_only = RequestContext.get(:current_username) === User.PUBLIC_USERNAME Log.debug("backend search received params: #{params.inspect}") query = if params[:q] Solr::Query.create_keyword_search(params[:q]) elsif params[:aq] && params[:aq]['query'] Solr::Query.create_advanced_search(params[:aq], protect_unpublished: show_published_only) else Solr::Query.create_match_all_query end query.pagination(params[:page], params[:page_size]). set_repo_id(repo_id). set_record_types(params[:type]). show_suppressed(show_suppressed). show_published_only(show_published_only). set_excluded_ids(params[:exclude]). set_filter(params[:filter]). set_filter_queries(params[:filter_query]). set_facets(params[:facet], (params[:facet_mincount] || 0)). set_sort(params[:sort]). set_root_record(params[:root_record]). highlighting(params[:hl]). set_writer_type( params[:dt] || "json" ) query.remove_csv_header if ( params[:dt] == "csv" and params[:no_csv_header] ) query.limit_fields_to(params[:fields]) if params[:fields] && (AppConfig[:limit_csv_fields] || params[:dt] != "csv") results = Solr.search(query) if params[:resolve] # As with the ArchivesSpace API, resolving a field gives a way of # returning linked records without having to make multiple queries. # # In the case of searching, a resolve parameter like: # # &resolve[]=repository:id # # will take the (stored) field value for "repository" and search for # that value in the "id" field of other Solr documents. Any document(s) # returned will be inserted into the search response under the key # "_resolved_repository". # # Since you might want to resolve a multi-valued field, we'll use the # following format: # # "_resolved_myfield": { # "/stored/value/1": [{... matched record 1...}, {... matched record 2...}], # "/stored/value/2": [{... matched record 1...}, {... matched record 2...}] # } # # To avoid the inlined resolved records being unreasonably large, you can # also specify a custom resolver to be used when rendering the record. # For example, the query: # # &resolve[]=resource:id@compact_resource # # will use the "compact_resource" resolver to render the inlined resource # records. This is defined by `search_resolver_compact_resource.rb`. You # can define as many of these classes as needed, and they'll be available # via the API in this same way. resolver = SearchResolver.new(params[:resolve]) resolver.resolve(results) end results end |
.search_csv(params, repo_id) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'backend/app/model/search.rb', line 171 def self.search_csv( params, repo_id ) # first let's get a json response with the number of pages p = params.dup p[:dt] = "json" result = search(p, repo_id) total_pages = result["last_page"].to_i || 2 page = 2 # we start on the second page bc the first will have headers Enumerator.new do |y| # we get page 1 of csv w headers y << search(params, repo_id) params[:no_csv_header] = true while page <= total_pages params[:page] = page y << search(params, repo_id) page +=1 end end end |
Instance Method Details
#allow_dates? ⇒ Boolean
74 75 76 77 78 79 80 81 |
# File 'public/app/models/search.rb', line 74 def allow_dates? allow = true limit.split(",").each do |type| allow = false if type == 'subject' allow = false if type.start_with?('agent') end allow end |
#filters_blank? ⇒ Boolean
56 57 58 |
# File 'public/app/models/search.rb', line 56 def filters_blank? filter_from_year.blank? && filter_to_year.blank? && filter_q.all?(&:blank?) end |
#get_filter_q_arr(url = nil) ⇒ Object
96 97 98 99 100 101 102 103 104 |
# File 'public/app/models/search.rb', line 96 def get_filter_q_arr(url = nil) fqa = [] self[:filter_q].each do |v| Rails.logger.debug("v: #{v} CGI-escaped: #{CGI.escape(v)}") uri = (url)? url.sub("&filter_q[]=#{CGI.escape(v)}", "") : '' fqa.push({'v' => v, 'uri' => uri}) end fqa end |
#get_filter_q_params ⇒ Object
88 89 90 91 92 93 94 |
# File 'public/app/models/search.rb', line 88 def get_filter_q_params params = '' self[:filter_q].each do |v| params += "&filter_q[]=#{CGI.escape(v)}" end params end |
#has_query? ⇒ Boolean
60 61 62 |
# File 'public/app/models/search.rb', line 60 def has_query? have_contents?(q) end |
#have_contents?(year_array) ⇒ Boolean
64 65 66 67 68 69 70 71 72 |
# File 'public/app/models/search.rb', line 64 def have_contents?(year_array) have = false year_array.each do |year| unless year.strip == '' have = true end end have end |
#search_dates_within? ⇒ Boolean
83 84 85 |
# File 'public/app/models/search.rb', line 83 def search_dates_within? dates_within && !dates_searched && filter_from_year.empty? && filter_to_year.empty? end |