Class: Typesensual::Search
- Inherits:
-
Object
- Object
- Typesensual::Search
- Includes:
- StateHelpers
- Defined in:
- lib/typesensual/search.rb,
lib/typesensual/search/hit.rb,
lib/typesensual/search/facet.rb,
lib/typesensual/search/results.rb,
lib/typesensual/search/grouped_hit.rb
Defined Under Namespace
Classes: Facet, GroupedHit, Hit, Results
Class Method Summary collapse
-
.multi(*searches) ⇒ Object
Perform multiple searches in one request.
Instance Method Summary collapse
-
#exclude_fields(*fields) ⇒ self
Add fields to exclude from the search result documents.
-
#facet(facets) ⇒ self
Add a field to facet to the search.
-
#filter(filter) ⇒ self
Add a filter to the search.
-
#group_by(*fields) ⇒ self
Add fields to group the search results by.
-
#include_fields(*fields) ⇒ self
Add fields to include in the search result documents.
-
#initialize(collection:, query:, query_by:) ⇒ Search
constructor
Initialize a new search object for a collection.
-
#load ⇒ Typesensual::Search::Results
Load the results from the search query.
-
#page(number) ⇒ self
Set the page number to return.
-
#per(count) ⇒ self
Set the number of results to return per page.
-
#query ⇒ Hash
Generate the query document.
-
#set(values) ⇒ self
Set additional parameters to pass to the search.
-
#sort(value) ⇒ self
Add a sort to the search.
Constructor Details
#initialize(collection:, query:, query_by:) ⇒ Search
Initialize a new search object for a collection
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 |
# File 'lib/typesensual/search.rb', line 25 def initialize(collection:, query:, query_by:) @filter_by = [] @sort_by = [] @facet_by = [] @facet_query = [] # this is just used by the Results class to determine names for facets @facet_keys = [] @facet_return_parent = [] @include_fields = [] @exclude_fields = [] @group_by = [] @params = {} @collection = collection @query = query if query_by.is_a?(Hash) @query_by = query_by.keys @query_by_weights = query_by.values elsif query_by.is_a?(String) || query_by.is_a?(Symbol) @query_by = [query_by] else @query_by = query_by end end |
Class Method Details
.multi(*searches) ⇒ <Typesensual::Search::Results> .multi(searches) ⇒ {Object => Typesensual::Search::Results}
Perform multiple searches in one request. There are two variants of this method, one which takes a list of anonymous queries and one which takes a hash of named queries. Named queries will probably be more readable for more than a couple of queries, but anonymous queries can be destructured directly.
Both versions accept either a Search instance or a hash of search parameters.
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/typesensual/search.rb', line 281 def self.multi(*searches) # If we have one argument and it's a hash, we're doing named searches if searches.count == 1 && searches.first.is_a?(Hash) keys = searches.first.keys searches = searches.first.values end results = client.multi_search.perform({ searches: searches.flatten.map(&:query) }) # Wrap our results in Result objects wrapped_results = results['results'].map do |result| exception = exception_for(result) if result['code'] exception || Results.new(result, search: self) end # If we're doing named searches, re-key the results if keys keys.zip(wrapped_results).to_h else wrapped_results end end |
Instance Method Details
#exclude_fields(*fields) ⇒ self
Add fields to exclude from the search result documents
213 214 215 216 |
# File 'lib/typesensual/search.rb', line 213 def exclude_fields(*fields) @exclude_fields += fields.map(&:to_s) self end |
#facet(facets: Symbol, String, Array) ⇒ self #facet(facets: Hash) ⇒ self
Add a field to facet to the search
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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/typesensual/search.rb', line 132 def facet(facets) if facets.is_a?(Hash) facets.each do |key, value| @facet_keys << key.to_s if value.is_a?(String) # Basic facet searching with a string query @facet_by << key.to_s @facet_query << "#{key}:#{value}" if value elsif value.is_a?(Hash) # Advanced faceting with sort, ranges, return_parent, and query facet_string = key.to_s facet_params = {} # Sort parameters case value[:sort] when Hash raise ArgumentError, 'Facet sort_by must have one key' if value[:sort].count != 1 sort_key, sort_direction = value[:sort].first facet_params[:sort_by] = "#{sort_key}:#{sort_direction}" when Symbol facet_params[:sort_by] = "_alpha:#{value[:sort]}" when String facet_params[:sort_by] = value[:sort] when nil nil else raise ArgumentError, 'Facet sort_by must be a Hash, Symbol, or String' end # Range parameters if value[:ranges].is_a?(Hash) ranges = value[:ranges].transform_values do |range| case range when Range raise ArgumentError, 'Facet ranges must exclude end' unless range.exclude_end? "[#{range.begin},#{range.end}]" when Array raise ArgumentError, 'Facet ranges must have two elements' unless range.count == 2 "[#{range.first},#{range.last}]" else raise ArgumentError, 'Facet ranges must be a Range or Array' end end facet_params.merge!(ranges) elsif !value[:ranges].nil? raise ArgumentError, 'Facet ranges must be a Hash' end # Format facet params unless facet_params.empty? facet_string += "(#{facet_params.map { |k, v| "#{k}:#{v}" }.join(',')})" end @facet_return_parent << key.to_s if value[:return_parent] @facet_query << "#{key}:#{value[:query]}" if value[:query] @facet_by << facet_string else @facet_by << key.to_s end end elsif facets.is_a?(Array) @facet_keys += facets.map(&:to_s) @facet_by += facets.map(&:to_s) else @facet_keys << facets.to_s @facet_by << facets.to_s end self end |
#filter(filter) ⇒ self
Add a filter to the search
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/typesensual/search.rb', line 70 def filter(filter) if filter.is_a?(Hash) @filter_by += filter.map { |key, value| "#{key}:#{value}" } elsif filter.is_a?(Array) @filter_by += filter.map(&:to_s) else @filter_by << filter.to_s end self end |
#group_by(*fields) ⇒ self
Add fields to group the search results by
221 222 223 224 |
# File 'lib/typesensual/search.rb', line 221 def group_by(*fields) @group_by += fields.map(&:to_s) self end |
#include_fields(*fields) ⇒ self
Add fields to include in the search result documents
205 206 207 208 |
# File 'lib/typesensual/search.rb', line 205 def include_fields(*fields) @include_fields += fields.map(&:to_s) self end |
#load ⇒ Typesensual::Search::Results
Load the results from the search query
255 256 257 258 259 |
# File 'lib/typesensual/search.rb', line 255 def load result = self.class.multi(self).first raise result if result.is_a?(StandardError) result end |
#page(number) ⇒ self
Set the page number to return
61 62 63 |
# File 'lib/typesensual/search.rb', line 61 def page(number) set(page: number) end |
#per(count) ⇒ self
Set the number of results to return per page
54 55 56 |
# File 'lib/typesensual/search.rb', line 54 def per(count) set(per_page: count) end |
#query ⇒ Hash
Generate the query document
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/typesensual/search.rb', line 236 def query { collection: @collection.name, filter_by: @filter_by.join(' && '), q: @query, query_by: @query_by&.join(','), query_by_weights: @query_by_weights&.join(','), sort_by: @sort_by&.join(','), facet_by: @facet_by&.join(','), facet_return_parent: @facet_return_parent&.join(','), facet_query: @facet_query&.join(','), include_fields: @include_fields&.join(','), exclude_fields: @exclude_fields&.join(','), group_by: @group_by&.join(',') }.merge(@params).compact end |
#set(values) ⇒ self
Set additional parameters to pass to the search
229 230 231 232 |
# File 'lib/typesensual/search.rb', line 229 def set(values) @params.merge!(values) self end |
#sort(value) ⇒ self
Add a sort to the search
86 87 88 89 90 91 92 93 |
# File 'lib/typesensual/search.rb', line 86 def sort(value) if value.is_a?(Hash) @sort_by += value.map { |key, direction| "#{key}:#{direction}" } else @sort_by << value.to_s end self end |