Class: ElasticSearchQuery
- Inherits:
-
Object
- Object
- ElasticSearchQuery
- Defined in:
- lib/elastic_search_query.rb
Class Method Summary collapse
-
.append_query_filter(query, filter) ⇒ Object
this appends bools structure containing must, should and must_not in an existing query under the filter context if filter is not present in the existing query, the entire bool structure is assigned, if filter is present, then the bool structure is merged with the existing structure under the filter context finally the filter priovided in the method params is appended in the must clause.
-
.append_size_filter(query, size) ⇒ Object
sets the max number of results to be returned by the query.
-
.dis_max_query(queries = []) ⇒ Object
returns a structure of dis_max query.
-
.filtered_aggregation(name, aggregation, filter) ⇒ Object
constructs a structure that defines a single bucket which matches a specified filter.
- .function_score(query, seed) ⇒ Object
-
.get_bool_filter_structure ⇒ Object
returns basic bool structure with should, must and mus_not clause.
-
.get_constant_score_filter_structure(filter = {}, boost = 1) ⇒ Object
returns constant score filter structure.
-
.get_constant_score_query_structure(query = {}, boost = 1) ⇒ Object
returns constant score query structure.
-
.get_exists_filter(field) ⇒ Object
returns exists filter.
-
.get_filtered_structure ⇒ Object
returns filtered_structure.
-
.get_ids_filter_query(ids) ⇒ Object
builds ids query with provided values.
-
.get_ids_query_structure ⇒ Object
returns the structure for ids matching.
-
.get_match_phrase_prefix_query(field, prefix) ⇒ Object
returns structure for match_phrase_prefix.
-
.get_metrics_aggregations_query(name, comparator, field_name) ⇒ Object
returns a generic metrics aggregation by providing the comparator.
-
.get_nested_aggregation_query(name, path, aggregation) ⇒ Object
this helps to contruct a structure where we can use aggregations on the nested objects also.
-
.get_nested_exists_query(field_name) ⇒ Object
get nested query to search on nested objects.
-
.get_nested_filter_structure(path, query = {}) ⇒ Object
With Elasticsearch 6.1 nested filter has been replaced with nested query nested filter structure.
-
.get_nested_query_structure(path, query = {}, score_mode = nil) ⇒ Object
returns nested query structure.
-
.get_nested_terms_query(path, field, value) ⇒ Object
returns nested terms query.
-
.get_query_bool_structure ⇒ Object
returns query bool structure.
-
.get_range_query(field, from, to) ⇒ Object
returns range query.
-
.get_reverse_nested_aggs(name, aggregations) ⇒ Object
returns a reverse nested structure.
- .get_script_score_function_structure ⇒ Object
-
.get_sort_subquery(sort_fields = []) ⇒ Object
used to append sort query so that the result is sorted based on the sort_fields provided.
-
.get_term_boost_query(field, value, boost) ⇒ Object
term boost query.
-
.get_term_filter_query(field, value, cache_flag = false) ⇒ Object
term filter query.
- .get_terms_aggregation_structure(name, field_name, include_array = [], script = "", size = nil) ⇒ Object
-
.get_terms_filter_query(field, value) ⇒ Object
returns terms_filter_query.
-
.get_terms_structure_with_aggregation(name, field_name, aggregation, include_array = [], script = "") ⇒ Object
constructs an aggregation structure based on field_name provided this dynamically builds buckets on the basis of field_name and provides the aggregations accordingly if field_name = genre and genre has values (rock, jazz, thrash metal), then aggregations will be based on these three genres.
-
.get_top_hits_aggregations(name, size, sort, source = []) ⇒ Object
constraucts a top_hits structure this aggregator is intended to be used as a sub aggregator, so that the top matching documents can be aggregated per bucket.
-
.merge_bool_query(main_query, query) ⇒ Object
merges bool queries into the main_query.
-
.percentile_aggregation(aggregation_name, field, percentile_points) ⇒ Object
calculates percentiles based on the field and provided percentile points.
-
.range_aggregation(aggregation_name, field, ranges) ⇒ Object
used for bucketing the response based on the field and range provided sample range [{ “to” : 100.0 },{ “from” : 100.0, “to” : 200.0 },{ “from” : 200.0 }].
-
.script_scoring_query(query, functions, boost_mode = "replace") ⇒ Object
to modify the score of documents that are retrieved by a query.
Class Method Details
.append_query_filter(query, filter) ⇒ Object
this appends bools structure containing must, should and must_not in an existing query under the filter context if filter is not present in the existing query, the entire bool structure is assigned, if filter is present, then the bool structure is merged with the existing structure under the filter context finally the filter priovided in the method params is appended in the must clause
428 429 430 431 432 433 434 435 436 437 438 439 |
# File 'lib/elastic_search_query.rb', line 428 def self.append_query_filter(query, filter) bool_query = get_bool_filter_structure if query[:query][:bool][:filter].nil? query[:query][:bool][:filter] = bool_query else bool_query[:bool].each { |key, val| query[:query][:bool][:filter][:bool][key] = [] unless query[:query][:bool][:filter][:bool].key? (key) } end query[:query][:bool][:filter][:bool][:must].push(filter) query end |
.append_size_filter(query, size) ⇒ Object
sets the max number of results to be returned by the query
442 443 444 445 |
# File 'lib/elastic_search_query.rb', line 442 def self.append_size_filter(query, size) query[:size] = size query end |
.dis_max_query(queries = []) ⇒ Object
returns a structure of dis_max query.
374 375 376 377 378 379 380 381 |
# File 'lib/elastic_search_query.rb', line 374 def self.dis_max_query queries=[] raise ArgumentError.new("queries is not an Array") unless queries.instance_of? Array return { dis_max: { queries: queries } } end |
.filtered_aggregation(name, aggregation, filter) ⇒ Object
constructs a structure that defines a single bucket which matches a specified filter
301 302 303 304 305 306 307 308 309 310 |
# File 'lib/elastic_search_query.rb', line 301 def self.filtered_aggregation name, aggregation, filter { :aggs => { name.intern => { filter: filter, aggs: aggregation } } } end |
.function_score(query, seed) ⇒ Object
357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/elastic_search_query.rb', line 357 def self.function_score query, seed { function_score: { query: query, functions: [ { random_score: { seed: seed } } ] } } end |
.get_bool_filter_structure ⇒ Object
returns basic bool structure with should, must and mus_not clause
165 166 167 168 169 170 171 172 173 |
# File 'lib/elastic_search_query.rb', line 165 def self.get_bool_filter_structure { bool: { must: [], should: [], must_not: [] } } end |
.get_constant_score_filter_structure(filter = {}, boost = 1) ⇒ Object
returns constant score filter structure
16 17 18 19 20 21 22 23 |
# File 'lib/elastic_search_query.rb', line 16 def self.get_constant_score_filter_structure filter = {}, boost = 1 { :constant_score => { :filter => filter, :boost => boost } } end |
.get_constant_score_query_structure(query = {}, boost = 1) ⇒ Object
returns constant score query structure
26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/elastic_search_query.rb', line 26 def self.get_constant_score_query_structure query = {}, boost = 1 { constant_score: { filter: { bool: { must: query } }, boost: boost } } end |
.get_exists_filter(field) ⇒ Object
returns exists filter
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/elastic_search_query.rb', line 40 def self.get_exists_filter field { constant_score: { filter: { exists: { field: field } } } } end |
.get_filtered_structure ⇒ Object
returns filtered_structure
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/elastic_search_query.rb', line 120 def self.get_filtered_structure { bool: { must: [], should: [], must_not: [], filter: { bool: { must: [], should: [], must_not: [] } } } } end |
.get_ids_filter_query(ids) ⇒ Object
builds ids query with provided values
290 291 292 293 294 |
# File 'lib/elastic_search_query.rb', line 290 def self.get_ids_filter_query ids ids_query_structure = get_ids_query_structure ids_query_structure[:ids][:values] = ids ids_query_structure end |
.get_ids_query_structure ⇒ Object
returns the structure for ids matching
7 8 9 10 11 12 13 |
# File 'lib/elastic_search_query.rb', line 7 def self.get_ids_query_structure { :ids => { :values => [] } } end |
.get_match_phrase_prefix_query(field, prefix) ⇒ Object
returns structure for match_phrase_prefix
79 80 81 82 83 84 85 86 |
# File 'lib/elastic_search_query.rb', line 79 def self.get_match_phrase_prefix_query field, prefix raise ArgumentError.new("field and prefix should be strings") unless (field.is_a? String) && (prefix.is_a? String) return { :match_phrase_prefix => { field => prefix } } end |
.get_metrics_aggregations_query(name, comparator, field_name) ⇒ Object
returns a generic metrics aggregation by providing the comparator
263 264 265 266 267 268 269 270 271 |
# File 'lib/elastic_search_query.rb', line 263 def self.get_metrics_aggregations_query name, comparator, field_name query = { name => { comparator => { field: field_name } } } end |
.get_nested_aggregation_query(name, path, aggregation) ⇒ Object
this helps to contruct a structure where we can use aggregations on the nested objects also.
278 279 280 281 282 283 284 285 286 287 |
# File 'lib/elastic_search_query.rb', line 278 def self.get_nested_aggregation_query name, path, aggregation query = { name => { nested: { path: path }, aggregations: aggregation } } end |
.get_nested_exists_query(field_name) ⇒ Object
get nested query to search on nested objects
411 412 413 414 415 416 417 418 419 420 |
# File 'lib/elastic_search_query.rb', line 411 def self.get_nested_exists_query field_name { nested: { path: field_name, query: { match_all: {} } } } end |
.get_nested_filter_structure(path, query = {}) ⇒ Object
With Elasticsearch 6.1 nested filter has been replaced with nested query nested filter structure
54 55 56 57 58 59 60 61 |
# File 'lib/elastic_search_query.rb', line 54 def self.get_nested_filter_structure path, query = {} { :nested => { :path => path, :query => query } } end |
.get_nested_query_structure(path, query = {}, score_mode = nil) ⇒ Object
returns nested query structure
64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/elastic_search_query.rb', line 64 def self.get_nested_query_structure path, query = {}, score_mode=nil raise ArgumentError.new("path has to be a string") unless (path.is_a? String) subquery = { :nested => { :path => path, :query => query } } if Constants::FUNCTION_SCORE_METHODS.include? score_mode subquery[:nested][:score_mode] = score_mode end return subquery end |
.get_nested_terms_query(path, field, value) ⇒ Object
returns nested terms query
150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/elastic_search_query.rb', line 150 def self.get_nested_terms_query(path, field, value) raise "Cannot append terms query to #{value} which is not an array" unless value.is_a?(Array) { nested: { path: path, query: { terms: { field => value } } } } end |
.get_query_bool_structure ⇒ Object
returns query bool structure
176 177 178 179 180 181 182 183 184 185 |
# File 'lib/elastic_search_query.rb', line 176 def self.get_query_bool_structure { query:{ bool: { filter:{ } } } } end |
.get_range_query(field, from, to) ⇒ Object
returns range query
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/elastic_search_query.rb', line 138 def self.get_range_query field, from, to q = { :range=> { field => {} } } q[:range][field][:from] = from if from.present? q[:range][field][:to] = to if to.present? return q end |
.get_reverse_nested_aggs(name, aggregations) ⇒ Object
returns a reverse nested structure
230 231 232 233 234 235 236 237 |
# File 'lib/elastic_search_query.rb', line 230 def self.get_reverse_nested_aggs name, aggregations { name => { "reverse_nested": {}, "aggs": aggregations } } end |
.get_script_score_function_structure ⇒ Object
399 400 401 402 403 404 405 406 407 408 |
# File 'lib/elastic_search_query.rb', line 399 def self.get_script_score_function_structure return { script_score: { script: { params: {}, inline: '' } } } end |
.get_sort_subquery(sort_fields = []) ⇒ Object
used to append sort query so that the result is sorted based on the sort_fields provided
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/elastic_search_query.rb', line 189 def self.get_sort_subquery sort_fields=[] raise "Cannot append sort query which is not an array" unless sort_fields.is_a?(Array) sort = [] sort_fields.each do |field| if field.is_a? Hash field.each do |key, order| next unless (order=="asc" || order=="desc") sort << {key => {"order" => order}} end elsif (field.is_a? String) || (field.is_a? Symbol) sort << field.to_s end end return sort end |
.get_term_boost_query(field, value, boost) ⇒ Object
term boost query
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/elastic_search_query.rb', line 98 def self.get_term_boost_query field, value, boost { :term => { field => { :value => value, :boost => boost } } } end |
.get_term_filter_query(field, value, cache_flag = false) ⇒ Object
term filter query
89 90 91 92 93 94 95 |
# File 'lib/elastic_search_query.rb', line 89 def self.get_term_filter_query(field, value, cache_flag = false) { term: { field => value } } end |
.get_terms_aggregation_structure(name, field_name, include_array = [], script = "", size = nil) ⇒ Object
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/elastic_search_query.rb', line 239 def self.get_terms_aggregation_structure name, field_name, include_array = [], script = "", size = nil query = { name => { terms: { field: field_name } } } query[name][:terms][:include] = include_array if include_array.present? if script.present? query[name][:terms].delete(:field) query[name][:terms][:script] = script end if size.present? size = 1 if size == 0 #size 0 is not supported since ES 5 query[name][:terms][:size] = size end query end |
.get_terms_filter_query(field, value) ⇒ Object
returns terms_filter_query
110 111 112 113 114 115 116 117 |
# File 'lib/elastic_search_query.rb', line 110 def self.get_terms_filter_query(field, value) raise "Cannot append terms query to #{value} which is not an array" unless value.is_a?(Array) { terms: { field => value } } end |
.get_terms_structure_with_aggregation(name, field_name, aggregation, include_array = [], script = "") ⇒ Object
constructs an aggregation structure based on field_name provided this dynamically builds buckets on the basis of field_name and provides the aggregations accordingly if field_name = genre and genre has values (rock, jazz, thrash metal), then aggregations will be based on these three genres
351 352 353 354 355 |
# File 'lib/elastic_search_query.rb', line 351 def self.get_terms_structure_with_aggregation name, field_name, aggregation, include_array = [], script = "" query = get_terms_aggregation_structure name, field_name, include_array, script query[name][:aggs] = aggregation return query end |
.get_top_hits_aggregations(name, size, sort, source = []) ⇒ Object
constraucts a top_hits structure this aggregator is intended to be used as a sub aggregator, so that the top matching documents can be aggregated per bucket
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/elastic_search_query.rb', line 212 def self.get_top_hits_aggregations name, size, sort, source = [] query = { name => { "top_hits": { "size": size } } }.with_indifferent_access query[name]["top_hits"]["sort"] = sort if sort.present? if source.present? query[name]["top_hits"]["_source"] = { "include": source } end query end |
.merge_bool_query(main_query, query) ⇒ Object
merges bool queries into the main_query
450 451 452 453 454 455 456 457 458 459 460 |
# File 'lib/elastic_search_query.rb', line 450 def self.merge_bool_query(main_query, query) query[:bool].each { |key, val| if main_query[:bool].key?(key) main_query[:bool][key] = Array.new([main_query[:bool][key]]) << val main_query[:bool][key].flatten! else main_query[:bool][key] = val end } main_query end |
.percentile_aggregation(aggregation_name, field, percentile_points) ⇒ Object
calculates percentiles based on the field and provided percentile points
316 317 318 319 320 321 322 323 324 325 |
# File 'lib/elastic_search_query.rb', line 316 def self.percentile_aggregation aggregation_name, field, percentile_points { aggregation_name.intern => { :percentiles => { :field => field, :percents => percentile_points } } } end |
.range_aggregation(aggregation_name, field, ranges) ⇒ Object
used for bucketing the response based on the field and range provided sample range [{ “to” : 100.0 },{ “from” : 100.0, “to” : 200.0 },{ “from” : 200.0 }]
332 333 334 335 336 337 338 339 340 341 |
# File 'lib/elastic_search_query.rb', line 332 def self.range_aggregation aggregation_name, field, ranges { aggregation_name.intern => { :range => { :field => field, :ranges => ranges } } } end |
.script_scoring_query(query, functions, boost_mode = "replace") ⇒ Object
to modify the score of documents that are retrieved by a query
387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/elastic_search_query.rb', line 387 def self.script_scoring_query(query, functions, boost_mode="replace") return query.except(:query).merge({ query: { function_score: { query: query[:query], functions: functions, boost_mode: boost_mode } } }) end |