Class: Chewy::Query
- Includes:
- Loading, Pagination, Scoping, Enumerable
- Defined in:
- lib/chewy/query.rb,
lib/chewy/query/compose.rb,
lib/chewy/query/filters.rb,
lib/chewy/query/loading.rb,
lib/chewy/query/scoping.rb,
lib/chewy/query/criteria.rb,
lib/chewy/query/nodes/or.rb,
lib/chewy/query/nodes/and.rb,
lib/chewy/query/nodes/not.rb,
lib/chewy/query/nodes/raw.rb,
lib/chewy/query/nodes/base.rb,
lib/chewy/query/nodes/bool.rb,
lib/chewy/query/nodes/expr.rb,
lib/chewy/query/pagination.rb,
lib/chewy/query/nodes/equal.rb,
lib/chewy/query/nodes/field.rb,
lib/chewy/query/nodes/query.rb,
lib/chewy/query/nodes/range.rb,
lib/chewy/query/nodes/exists.rb,
lib/chewy/query/nodes/prefix.rb,
lib/chewy/query/nodes/regexp.rb,
lib/chewy/query/nodes/script.rb,
lib/chewy/query/nodes/missing.rb,
lib/chewy/query/nodes/has_child.rb,
lib/chewy/query/nodes/match_all.rb,
lib/chewy/query/nodes/has_parent.rb,
lib/chewy/query/nodes/has_relation.rb,
lib/chewy/query/pagination/kaminari.rb,
lib/chewy/query/pagination/will_paginate.rb
Overview
Query allows you to create ES search requests with convenient chainable DSL. Queries are lazy evaluated and might be merged. The same DSL is used for whole index or individual types query build.
UsersIndex.filter{ age < 42 }.query(text: {name: 'Alex'}).limit(20)
UsersIndex::User.filter{ age < 42 }.query(text: {name: 'Alex'}).limit(20)
Defined Under Namespace
Modules: Compose, Loading, Nodes, Pagination, Scoping Classes: Criteria, Filters
Instance Attribute Summary collapse
-
#_indexes ⇒ Object
readonly
Returns the value of attribute _indexes.
-
#_types ⇒ Object
readonly
Returns the value of attribute _types.
-
#criteria ⇒ Object
readonly
Returns the value of attribute criteria.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Comparation with other query or collection If other is collection - search request is executed and result is used for comparation.
- #_build_fqn_aggs ⇒ Object
-
#_build_named_aggs ⇒ Object
In this simplest of implementations each named aggregation must be uniquely named.
- #_get_fully_qualified_named_agg(str) ⇒ Object
-
#aggregations(params = nil) ⇒ Object
(also: #aggs)
Sets elasticsearch
aggregationssearch request param. -
#boost_factor(factor, options = {}) ⇒ Object
Adds a boost factor to the search request.
-
#boost_mode(value) ⇒ Object
Sets the boost mode for custom scoring/boosting.
-
#decay(function, field, options = {}) ⇒ Object
Add a decay scoring to the search.
-
#delete_all ⇒ Object
Deletes all records matching a query.
-
#explain(value = nil) ⇒ Object
Adds
explainparameter to search request. -
#facets(params = nil) ⇒ Object
Adds facets section to the search request.
-
#field_value_factor(settings, options = {}) ⇒ Object
Add a field value scoring to the search.
-
#filter(params = nil, &block) ⇒ Object
Adds one or more filter to the search request Internally filters are stored as an array While the full query compilation this array compiles according to
:filter_modeoption value. -
#filter_mode(value) ⇒ Object
Sets query compilation mode for search request.
-
#find(*ids) ⇒ Object
Find all records matching a query.
-
#highlight(value) ⇒ Object
Elasticsearch highlight query option support.
-
#initialize(*indexes_or_types_and_options) ⇒ Query
constructor
A new instance of Query.
-
#limit(value) ⇒ Object
Sets elasticsearch
sizesearch request param Default value is set in the elasticsearch and is 10. -
#merge(other) ⇒ Object
Merges two queries.
-
#min_score(value) ⇒ Object
Elasticsearch minscore option support.
-
#none ⇒ Object
Marks the criteria as having zero records.
-
#offset(value) ⇒ Object
Sets elasticsearch
fromsearch request param. -
#only(*params) ⇒ Object
Sets search request field list.
-
#only!(*params) ⇒ Object
Cleans up previous search field list and sets the new one.
-
#order(*params) ⇒ Object
Sets search request sorting.
-
#post_filter(params = nil, &block) ⇒ Object
Adds one or more post_filter to the search request Internally post_filters are stored as an array While the full query compilation this array compiles according to
:post_filter_modeoption value. -
#post_filter_mode(value) ⇒ Object
Acts the same way as ‘filter_mode`, but used for `post_filter`.
-
#query(params) ⇒ Object
Adds one or more query to the search request Internally queries are stored as an array While the full query compilation this array compiles according to
:query_modeoption value. -
#query_mode(value) ⇒ Object
Sets query compilation mode for search request.
-
#random_score(seed = Time.now, options = {}) ⇒ Object
Adds a random score to the search request.
-
#reorder(*params) ⇒ Object
Cleans up previous search sorting and sets the new one.
-
#rescore(value) ⇒ Object
Elasticsearch rescore query option support.
-
#score_mode(value) ⇒ Object
Sets the scoring mode for combining function scores/boosts Not used if no score functions are specified.
-
#script_fields(value) ⇒ Object
Adds
script_fieldsparameter to search request. -
#script_score(script, options = {}) ⇒ Object
Adds a script function to score the search request.
-
#search_type(val) ⇒ Object
Sets
search_typefor request. -
#strategy(value = nil) ⇒ Object
Setups strategy for top-level filtered query.
-
#suggest(params = nil) ⇒ Object
Sets elasticsearch
suggestsearch request param. -
#timed_out ⇒ Object
Returns request timed_out as reported by elasticsearch.
-
#timeout(value) ⇒ Object
A search timeout, bounding the search request to be executed within the specified time value and bail with the hits accumulated up to that point when expired.
-
#took ⇒ Object
Returns request total time elapsed as reported by elasticsearch.
-
#types(*params) ⇒ Object
Specify types participating in the search result Works via
typesfilter. -
#types!(*params) ⇒ Object
Acts the same way as
types, but cleans up previously set types.
Methods included from Pagination
Methods included from Loading
Methods included from Scoping
Constructor Details
#initialize(*indexes_or_types_and_options) ⇒ Query
Returns a new instance of Query.
26 27 28 29 30 31 32 |
# File 'lib/chewy/query.rb', line 26 def initialize * @options = . @_types = .select { |klass| klass < Chewy::Type } @_indexes = .select { |klass| klass < Chewy::Index } @_indexes |= @_types.map(&:index) @criteria = Criteria.new end |
Instance Attribute Details
#_indexes ⇒ Object (readonly)
Returns the value of attribute _indexes.
24 25 26 |
# File 'lib/chewy/query.rb', line 24 def _indexes @_indexes end |
#_types ⇒ Object (readonly)
Returns the value of attribute _types.
24 25 26 |
# File 'lib/chewy/query.rb', line 24 def _types @_types end |
#criteria ⇒ Object (readonly)
Returns the value of attribute criteria.
24 25 26 |
# File 'lib/chewy/query.rb', line 24 def criteria @criteria end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
24 25 26 |
# File 'lib/chewy/query.rb', line 24 def @options end |
Instance Method Details
#==(other) ⇒ Object
Comparation with other query or collection If other is collection - search request is executed and result is used for comparation
UsersIndex.filter(term: {name: 'Johny'}) == UsersIndex.filter(term: {name: 'Johny'}) # => true
UsersIndex.filter(term: {name: 'Johny'}) == UsersIndex.filter(term: {name: 'Johny'}).to_a # => true
UsersIndex.filter(term: {name: 'Johny'}) == UsersIndex.filter(term: {name: 'Winnie'}) # => false
42 43 44 45 46 47 48 |
# File 'lib/chewy/query.rb', line 42 def == other super || if other.is_a?(self.class) other.criteria == criteria else to_a == other end end |
#_build_fqn_aggs ⇒ Object
530 531 532 533 534 535 536 537 538 539 540 541 542 |
# File 'lib/chewy/query.rb', line 530 def _build_fqn_aggs named_aggs = {} @_indexes.each do |index| named_aggs[index.to_s.downcase] ||= {} index.types.each do |type| named_aggs[index.to_s.downcase][type.to_s.downcase] ||= {} type._agg_defs.each do |agg_name, prc| named_aggs[index.to_s.downcase][type.to_s.downcase][agg_name.to_s.downcase] = prc.call end end end named_aggs end |
#_build_named_aggs ⇒ Object
In this simplest of implementations each named aggregation must be uniquely named
518 519 520 521 522 523 524 525 526 527 528 |
# File 'lib/chewy/query.rb', line 518 def _build_named_aggs named_aggs = {} @_indexes.each do |index| index.types.each do |type| type._agg_defs.each do |agg_name, prc| named_aggs[agg_name] = prc.call end end end named_aggs end |
#_get_fully_qualified_named_agg(str) ⇒ Object
544 545 546 547 548 549 550 |
# File 'lib/chewy/query.rb', line 544 def _get_fully_qualified_named_agg(str) parts = str.scan(/\A(\S+)#(\S+)\.(\S+)\z/).first idx = "#{parts[0]}index" type = "#{idx}::#{parts[1]}" agg_name = parts[2] @_fully_qualified_named_aggs[idx][type][agg_name] end |
#aggregations(params = nil) ⇒ Object Also known as: aggs
Sets elasticsearch aggregations search request param
UsersIndex.filter{ name == 'Johny' }.aggregations(category_id: {terms: {field: 'category_ids'}})
# => {body: {
query: {...},
aggregations: {
terms: {
field: 'category_ids'
}
}
}}
504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/chewy/query.rb', line 504 def aggregations params = nil @_named_aggs ||= _build_named_aggs @_fully_qualified_named_aggs ||= _build_fqn_aggs if params params = { params => @_named_aggs[params] } if params.is_a?(Symbol) params = { params => _get_fully_qualified_named_agg(params) } if params.is_a?(String) && params =~ /\A\S+#\S+\.\S+\z/ chain { criteria.update_aggregations params } else _response['aggregations'] || {} end end |
#boost_factor(factor, options = {}) ⇒ Object
Adds a boost factor to the search request. All scores are added to the search request and combinded according to boost_mode and score_mode
This probably only makes sense if you specify a filter for the boost factor as well
UsersIndex.boost_factor(23, filter: { term: { foo: :bar} })
# => {body:
query: {
function_score: {
query: { ...},
functions: [{
boost_factor: 23,
filter: { term: { foo: :bar } }
}]
} } }
393 394 395 396 |
# File 'lib/chewy/query.rb', line 393 def boost_factor(factor, = {}) scoring = .merge(boost_factor: factor.to_i) chain { criteria.update_scores scoring } end |
#boost_mode(value) ⇒ Object
Sets the boost mode for custom scoring/boosting. Not used if no score functions are specified Possible values:
-
:multiplyDefault value. Query score and function result are multiplied.Ex:
UsersIndex.boost_mode('multiply').script_score('doc['boost'].value') # => {body: {query: function_score: { query: {...}, boost_mode: 'multiply', functions: [ ... ] }}} -
:replaceOnly function result is used, query score is ignored. -
:sumQuery score and function score are added. -
:avgAverage of query and function score. -
:maxMax of query and function score. -
:minMin of query and function score.
Default value for :boost_mode might be changed with Chewy.score_mode config option.
725 726 727 |
# File 'lib/chewy/query.rb', line 725 def boost_mode value chain { criteria. boost_mode: value } end |
#decay(function, field, options = {}) ⇒ Object
Add a decay scoring to the search. All scores are added to the search request and combinded according to boost_mode and score_mode
The parameters have default values, but those may not be very useful for most applications.
UsersIndex.decay(
:gauss,
:field,
origin: '11, 12',
scale: '2km',
offset: '5km',
decay: 0.4,
filter: { foo: :bar})
# => {body:
query: {
gauss: {
query: { ...},
functions: [{
gauss: {
field: {
origin: '11, 12',
scale: '2km',
offset: '5km',
decay: 0.4
}
},
filter: { foo: :bar }
}]
} } }
484 485 486 487 488 489 490 |
# File 'lib/chewy/query.rb', line 484 def decay(function, field, = {}) = .extract!(:origin, :scale, :offset, :decay).delete_if { |_, v| v.nil? } scoring = .merge(function => { field => }) chain { criteria.update_scores scoring } end |
#delete_all ⇒ Object
Deletes all records matching a query.
UsersIndex.delete_all
UsersIndex.filter{ age <= 42 }.delete_all
UsersIndex::User.delete_all
UsersIndex::User.filter{ age <= 42 }.delete_all
899 900 901 902 903 904 905 906 907 908 909 910 911 |
# File 'lib/chewy/query.rb', line 899 def delete_all if Runtime.version > '2.0' plugins = Chewy.client.nodes.info(plugins: true)["nodes"].values.map { |item| item["plugins"] }.flatten raise PluginMissing, "install delete-by-query plugin" unless plugins.find { |item| item["name"] == 'delete-by-query' } end request = chain { criteria. simple: true }.send(:_request) ActiveSupport::Notifications.instrument 'delete_query.chewy', request: request, indexes: _indexes, types: _types, index: _indexes.one? ? _indexes.first : _indexes, type: _types.one? ? _types.first : _types do Chewy.client.delete_by_query(request) end end |
#explain(value = nil) ⇒ Object
Adds explain parameter to search request.
UsersIndex.filter(term: {name: 'Johny'}).explain
UsersIndex.filter(term: {name: 'Johny'}).explain(true)
UsersIndex.filter(term: {name: 'Johny'}).explain(false)
Calling explain without any arguments sets explanation flag to true. With explain: true, every result object has _explanation method
UsersIndex::User.filter(term: {name: 'Johny'}).explain.first._explanation # => {...}
62 63 64 |
# File 'lib/chewy/query.rb', line 62 def explain value = nil chain { criteria. explain: (value.nil? ? true : value) } end |
#facets(params = nil) ⇒ Object
Adds facets section to the search request. All the chained facets a merged and added to the search request
UsersIndex.facets(tags: {terms: {field: 'tags'}}).facets(ages: {terms: {field: 'age'}})
# => {body: {
query: {...},
facets: {tags: {terms: {field: 'tags'}}, ages: {terms: {field: 'age'}}}
}}
If called parameterless - returns result facets from ES performing request. Returns empty hash if no facets was requested or resulted.
345 346 347 348 349 350 351 352 |
# File 'lib/chewy/query.rb', line 345 def facets params = nil raise RemovedFeature, 'removed in elasticsearch 2.0' if Runtime.version >= '2.0' if params chain { criteria.update_facets params } else _response['facets'] || {} end end |
#field_value_factor(settings, options = {}) ⇒ Object
Add a field value scoring to the search. All scores are added to the search request and combinded according to boost_mode and score_mode
This function is only available in Elasticsearch 1.2 and greater
UsersIndex.field_value_factor(
{
field: :boost,
factor: 1.2,
modifier: :sqrt
}, filter: { foo: :bar})
# => {body:
query: {
function_score: {
query: { ...},
functions: [{
field_value_factor: {
field: :boost,
factor: 1.2,
modifier: :sqrt
},
filter: { foo: :bar }
}]
} } }
448 449 450 451 |
# File 'lib/chewy/query.rb', line 448 def field_value_factor(settings, = {}) scoring = .merge(field_value_factor: settings) chain { criteria.update_scores scoring } end |
#filter(params = nil, &block) ⇒ Object
Adds one or more filter to the search request Internally filters are stored as an array While the full query compilation this array compiles according to :filter_mode option value
By default it joins inside and filter See #filter_mode chainable method for more info.
Also this method supports block DSL. See Chewy::Query::Filters for more info.
UsersIndex.filter(term: {name: 'Johny'}).filter(range: {age: {lte: 42}})
UsersIndex::User.filter(term: {name: 'Johny'}).filter(range: {age: {lte: 42}})
UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 }
# => {body: {query: {filtered: {
query: {...},
filter: {and: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}
}}}}
If only one filter was specified, it will become a result filter as is, without joining.
UsersIndex.filter(term: {name: 'Johny'})
# => {body: {query: {filtered: {
query: {...},
filter: {term: {name: 'Johny'}}
}}}}
656 657 658 659 |
# File 'lib/chewy/query.rb', line 656 def filter params = nil, &block params = Filters.new(&block).__render__ if block chain { criteria.update_filters params } end |
#filter_mode(value) ⇒ Object
Sets query compilation mode for search request. Not used if only one filter for search is specified. Possible values:
-
:andDefault value. Filter compiles into anandfilter.Ex:
UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 } # => {body: {query: {filtered: { query: {...}, filter: {and: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}]} }}}} -
:orFilter compiles into anorfilter.Ex:
UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 }.filter_mode(:or) # => {body: {query: {filtered: { query: {...}, filter: {or: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}]} }}}} -
:mustFilter compiles into a boolmustfilter.Ex:
UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 }.filter_mode(:must) # => {body: {query: {filtered: { query: {...}, filter: {bool: {must: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}} }}}} -
:shouldFilter compiles into a boolshouldfilter.Ex:
UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 }.filter_mode(:should) # => {body: {query: {filtered: { query: {...}, filter: {bool: {should: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}} }}}} -
Any acceptable
minimum_should_matchvalue (1, ‘2’, ‘75%’) Filter compiles into boolshouldfilter withminimum_should_matchset.Ex:
UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 }.filter_mode('50%') # => {body: {query: {filtered: { query: {...}, filter: {bool: { should: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}], minimum_should_match: '50%' }} }}}}
Default value for :filter_mode might be changed with Chewy.filter_mode config option.
Chewy.filter_mode = :should
Chewy.filter_mode = '50%'
218 219 220 |
# File 'lib/chewy/query.rb', line 218 def filter_mode value chain { criteria. filter_mode: value } end |
#find(*ids) ⇒ Object
Find all records matching a query.
UsersIndex.find(42)
UsersIndex.filter{ age <= 42 }.find(42)
UsersIndex::User.find(42)
UsersIndex::User.filter{ age <= 42 }.find(42)
In all the previous examples find will return a single object. To get a collection - pass an array of ids.
UsersIndex::User.find(42, 7, 3) # array of objects with ids in [42, 7, 3]
UsersIndex::User.find([8, 13]) # array of objects with ids in [8, 13]
UsersIndex::User.find([42]) # array of the object with id == 42
927 928 929 930 931 932 |
# File 'lib/chewy/query.rb', line 927 def find *ids results = chain { criteria. simple: true }.filter { _id == ids.flatten }.to_a raise Chewy::DocumentNotFound.new("Could not find documents for ids #{ids.flatten}") if results.empty? ids.one? && !ids.first.is_a?(Array) ? results.first : results end |
#highlight(value) ⇒ Object
Elasticsearch highlight query option support
UsersIndex.query(...).highlight(fields: { ... })
312 313 314 |
# File 'lib/chewy/query.rb', line 312 def highlight value chain { criteria. highlight: value } end |
#limit(value) ⇒ Object
Sets elasticsearch size search request param Default value is set in the elasticsearch and is 10.
UsersIndex.filter{ name == 'Johny' }.limit(100)
# => {body: {
query: {...},
size: 100
}}
292 293 294 |
# File 'lib/chewy/query.rb', line 292 def limit value chain { criteria. size: Integer(value) } end |
#merge(other) ⇒ Object
Merges two queries. Merges all the values in criteria with the same rules as values added manually.
scope1 = UsersIndex.filter{ name == 'Johny' }
scope2 = UsersIndex.filter{ age <= 42 }
scope3 = UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 }
scope1.merge(scope2) == scope3 # => true
888 889 890 |
# File 'lib/chewy/query.rb', line 888 def merge other chain { criteria.merge!(other.criteria) } end |
#min_score(value) ⇒ Object
Elasticsearch minscore option support
UsersIndex.query(…).min_score(0.5)
328 329 330 |
# File 'lib/chewy/query.rb', line 328 def min_score value chain { criteria. min_score: value } end |
#none ⇒ Object
Marks the criteria as having zero records. This scope always returns empty array without touching the elasticsearch server. All the chained calls of methods don’t affect the result
UsersIndex.none.to_a
# => []
UsersIndex.query(text: {name: 'Johny'}).none.to_a
# => []
UsersIndex.none.query(text: {name: 'Johny'}).to_a
# => []
584 585 586 |
# File 'lib/chewy/query.rb', line 584 def none chain { criteria. none: true } end |
#offset(value) ⇒ Object
Sets elasticsearch from search request param
UsersIndex.filter{ name == 'Johny' }.offset(300)
# => {body: {
query: {...},
from: 300
}}
304 305 306 |
# File 'lib/chewy/query.rb', line 304 def offset value chain { criteria. from: Integer(value) } end |
#only(*params) ⇒ Object
Sets search request field list
UsersIndex.only(:first_name, :last_name).only(:age)
# => {body: {
query: {...},
fields: ['first_name', 'last_name', 'age']
}}
801 802 803 |
# File 'lib/chewy/query.rb', line 801 def only *params chain { criteria.update_fields params } end |
#only!(*params) ⇒ Object
Cleans up previous search field list and sets the new one
UsersIndex.only(:first_name, :last_name).only!(:age)
# => {body: {
query: {...},
fields: ['age']
}}
813 814 815 |
# File 'lib/chewy/query.rb', line 813 def only! *params chain { criteria.update_fields params, purge: true } end |
#order(*params) ⇒ Object
Sets search request sorting
UsersIndex.order(:first_name, :last_name).order(age: :desc).order(price: {order: :asc, mode: :avg})
# => {body: {
query: {...},
sort: ['first_name', 'last_name', {age: 'desc'}, {price: {order: 'asc', mode: 'avg'}}]
}}
777 778 779 |
# File 'lib/chewy/query.rb', line 777 def order *params chain { criteria.update_sort params } end |
#post_filter(params = nil, &block) ⇒ Object
Adds one or more post_filter to the search request Internally post_filters are stored as an array While the full query compilation this array compiles according to :post_filter_mode option value
By default it joins inside and filter See #post_filter_mode chainable method for more info.
Also this method supports block DSL. See Chewy::Query::Filters for more info.
UsersIndex.post_filter(term: {name: 'Johny'}).post_filter(range: {age: {lte: 42}})
UsersIndex::User.post_filter(term: {name: 'Johny'}).post_filter(range: {age: {lte: 42}})
UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }
# => {body: {
post_filter: {and: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}
}}
If only one post_filter was specified, it will become a result post_filter as is, without joining.
UsersIndex.post_filter(term: {name: 'Johny'})
# => {body: {
post_filter: {term: {name: 'Johny'}}
}}
687 688 689 690 |
# File 'lib/chewy/query.rb', line 687 def post_filter params = nil, &block params = Filters.new(&block).__render__ if block chain { criteria.update_post_filters params } end |
#post_filter_mode(value) ⇒ Object
Acts the same way as ‘filter_mode`, but used for `post_filter`. Note that it fallbacks by default to `Chewy.filter_mode` if `Chewy.post_filter_mode` is nil.
UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }.post_filter_mode(:and)
UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }.post_filter_mode(:should)
UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }.post_filter_mode('50%')
230 231 232 |
# File 'lib/chewy/query.rb', line 230 def post_filter_mode value chain { criteria. post_filter_mode: value } end |
#query(params) ⇒ Object
Adds one or more query to the search request Internally queries are stored as an array While the full query compilation this array compiles according to :query_mode option value
By default it joines inside must query See #query_mode chainable method for more info.
UsersIndex.query(text: {name: 'Johny'}).query(range: {age: {lte: 42}})
UsersIndex::User.query(text: {name: 'Johny'}).query(range: {age: {lte: 42}})
# => {body: {
query: {bool: {must: [{text: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}}
}}
If only one query was specified, it will become a result query as is, without joining.
UsersIndex.query(text: {name: 'Johny'})
# => {body: {
query: {text: {name: 'Johny'}}
}}
624 625 626 |
# File 'lib/chewy/query.rb', line 624 def query params chain { criteria.update_queries params } end |
#query_mode(value) ⇒ Object
Sets query compilation mode for search request. Not used if only one filter for search is specified. Possible values:
-
:mustDefault value. Query compiles into a boolmustquery.Ex:
UsersIndex.query(text: {name: 'Johny'}).query(range: {age: {lte: 42}}) # => {body: { query: {bool: {must: [{text: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}} }} -
:shouldQuery compiles into a boolshouldquery.Ex:
UsersIndex.query(text: {name: 'Johny'}).query(range: {age: {lte: 42}}).query_mode(:should) # => {body: { query: {bool: {should: [{text: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}} }} -
Any acceptable
minimum_should_matchvalue (1, ‘2’, ‘75%’) Query compiles into a boolshouldquery withminimum_should_matchset.Ex:
UsersIndex.query(text: {name: 'Johny'}).query(range: {age: {lte: 42}}).query_mode('50%') # => {body: { query: {bool: { should: [{text: {name: 'Johny'}}, {range: {age: {lte: 42}}}], minimum_should_match: '50%' }} }} -
:dis_maxQuery compiles into adis_maxquery.Ex:
UsersIndex.query(text: {name: 'Johny'}).query(range: {age: {lte: 42}}).query_mode(:dis_max) # => {body: { query: {dis_max: {queries: [{text: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}} }} -
Any Float value (0.0, 0.7, 1.0) Query compiles into a
dis_maxquery withtie_breakeroption set.Ex:
UsersIndex.query(text: {name: 'Johny'}).query(range: {age: {lte: 42}}).query_mode(0.7) # => {body: { query: {dis_max: { queries: [{text: {name: 'Johny'}}, {range: {age: {lte: 42}}}], tie_breaker: 0.7 }} }}
Default value for :query_mode might be changed with Chewy.query_mode config option.
Chewy.query_mode = :dis_max
Chewy.query_mode = '50%'
146 147 148 |
# File 'lib/chewy/query.rb', line 146 def query_mode value chain { criteria. query_mode: value } end |
#random_score(seed = Time.now, options = {}) ⇒ Object
Adds a random score to the search request. All scores are added to the search request and combinded according to boost_mode and score_mode
This probably only makes sense if you specify a filter for the random score as well.
If you do not pass in a seed value, Time.now will be used
UsersIndex.random_score(23, filter: { foo: :bar})
# => {body:
query: {
function_score: {
query: { ...},
functions: [{
random_score: { seed: 23 },
filter: { foo: :bar }
}]
} } }
417 418 419 420 |
# File 'lib/chewy/query.rb', line 417 def random_score(seed = Time.now, = {}) scoring = .merge(random_score: { seed: seed.to_i }) chain { criteria.update_scores scoring } end |
#reorder(*params) ⇒ Object
Cleans up previous search sorting and sets the new one
UsersIndex.order(:first_name, :last_name).order(age: :desc).reorder(price: {order: :asc, mode: :avg})
# => {body: {
query: {...},
sort: [{price: {order: 'asc', mode: 'avg'}}]
}}
789 790 791 |
# File 'lib/chewy/query.rb', line 789 def reorder *params chain { criteria.update_sort params, purge: true } end |
#rescore(value) ⇒ Object
Elasticsearch rescore query option support
UsersIndex.query(...).rescore(query: { ... })
320 321 322 |
# File 'lib/chewy/query.rb', line 320 def rescore value chain { criteria. rescore: value } end |
#score_mode(value) ⇒ Object
Sets the scoring mode for combining function scores/boosts Not used if no score functions are specified. Possible values:
-
:multiplyDefault value. Scores are multiplied.Ex:
UsersIndex.score_mode('multiply').script_score('doc['boost'].value') # => {body: {query: function_score: { query: {...}, score_mode: 'multiply', functions: [ ... ] }}} -
:sumScores are summed. -
:avgScores are averaged. -
:firstThe first function that has a matching filter is applied. -
:maxMaximum score is used. -
:minMinimum score is used
Default value for :score_mode might be changed with Chewy.score_mode config option.
Chewy.score_mode = :first
765 766 767 |
# File 'lib/chewy/query.rb', line 765 def score_mode value chain { criteria. score_mode: value } end |
#script_fields(value) ⇒ Object
Adds script_fields parameter to search request.
UsersIndex.script_fields(
distance: {
params: {
lat: 37.569976,
lon: -122.351591
},
script: "doc['coordinates'].distanceInMiles(lat, lon)"
}
)
76 77 78 |
# File 'lib/chewy/query.rb', line 76 def script_fields value chain { criteria.update_script_fields(value) } end |
#script_score(script, options = {}) ⇒ Object
Adds a script function to score the search request. All scores are added to the search request and combinded according to boost_mode and score_mode
UsersIndex.script_score("doc['boost'].value", params: { modifier: 2 })
# => {body:
query: {
function_score: {
query: { ...},
functions: [{
script_score: {
script: "doc['boost'].value * modifier",
params: { modifier: 2 }
}
}
}]
} } }
371 372 373 374 |
# File 'lib/chewy/query.rb', line 371 def script_score(script, = {}) scoring = { script_score: { script: script }.merge() } chain { criteria.update_scores scoring } end |
#search_type(val) ⇒ Object
Sets search_type for request. For instance, one can use search_type=count to fetch only total count of records or to fetch only aggregations without fetching records.
scope = UsersIndex.search_type(:count)
scope.count == 0 # no records actually fetched
scope.total == 10 # but we know a total count of them
scope = UsersIndex.aggs(max_age: { max: { field: 'age' } }).search_type(:count)
max_age = scope.aggs['max_age']['value']
875 876 877 |
# File 'lib/chewy/query.rb', line 875 def search_type val chain { .merge!(search_type: val) } end |
#strategy(value = nil) ⇒ Object
Setups strategy for top-level filtered query
UsersIndex.filter { name == 'Johny'}.strategy(:leap_frog)
# => {body: {
query: { filtered: {
filter: { term: { name: 'Johny' } },
strategy: 'leap_frog'
} }
}}
598 599 600 |
# File 'lib/chewy/query.rb', line 598 def strategy value = nil chain { criteria. strategy: value } end |
#suggest(params = nil) ⇒ Object
Sets elasticsearch suggest search request param
UsersIndex.suggest(name: {text: 'Joh', term: {field: 'name'}})
# => {body: {
query: {...},
suggest: {
text: 'Joh',
term: {
field: 'name'
}
}
}}
565 566 567 568 569 570 571 |
# File 'lib/chewy/query.rb', line 565 def suggest params = nil if params chain { criteria.update_suggest params } else _response['suggest'] || {} end end |
#timed_out ⇒ Object
Returns request timed_out as reported by elasticsearch
The timed_out value tells us whether the query timed out or not.
By default, search requests do not timeout. If low response times are more important to you than complete results, you can specify a timeout as 10 or “10ms” (10 milliseconds), or “1s” (1 second). See #timeout method.
UsersIndex.query(...).filter(...).timed_out
952 953 954 |
# File 'lib/chewy/query.rb', line 952 def timed_out _response['timed_out'] end |
#timeout(value) ⇒ Object
A search timeout, bounding the search request to be executed within the specified time value and bail with the hits accumulated up to that point when expired. Defaults to no timeout.
By default, the coordinating node waits to receive a response from all shards. If one node is having trouble, it could slow down the response to all search requests.
The timeout parameter tells the coordinating node how long it should wait before giving up and just returning the results that it already has. It can be better to return some results than none at all.
The response to a search request will indicate whether the search timed out and how many shards responded successfully:
...
"timed_out": true,
"_shards": {
"total": 5,
"successful": 4,
"failed": 1
},
...
The primary shard assigned to perform the index operation might not be available when the index operation is executed. Some reasons for this might be that the primary shard is currently recovering from a gateway or undergoing relocation. By default, the index operation will wait on the primary shard to become available for up to 1 minute before failing and responding with an error. The timeout parameter can be used to explicitly specify how long it waits.
UsersIndex.timeout("5000ms")
Timeout is not a circuit breaker.
It should be noted that this timeout does not halt the execution of the query, it merely tells the coordinating node to return the results collected so far and to close the connection. In the background, other shards may still be processing the query even though results have been sent.
Use the timeout because it is important to your SLA, not because you want to abort the execution of long running queries.
279 280 281 |
# File 'lib/chewy/query.rb', line 279 def timeout value chain { criteria. timeout: value } end |
#took ⇒ Object
Returns request total time elapsed as reported by elasticsearch
UsersIndex.query(...).filter(...).took
938 939 940 |
# File 'lib/chewy/query.rb', line 938 def took _response['took'] end |
#types(*params) ⇒ Object
Specify types participating in the search result Works via types filter. Always merged with another filters with the and filter.
UsersIndex.types(:admin, :manager).filters{ name == 'Johny' }.filters{ age <= 42 }
# => {body: {query: {filtered: {
query: {...},
filter: {and: [
{or: [
{type: {value: 'admin'}},
{type: {value: 'manager'}}
]},
{term: {name: 'Johny'}},
{range: {age: {lte: 42}}}
]}
}}}}
UsersIndex.types(:admin, :manager).filters{ name == 'Johny' }.filters{ age <= 42 }.filter_mode(:or)
# => {body: {query: {filtered: {
query: {...},
filter: {and: [
{or: [
{type: {value: 'admin'}},
{type: {value: 'manager'}}
]},
{or: [
{term: {name: 'Johny'}},
{range: {age: {lte: 42}}}
]}
]}
}}}}
849 850 851 |
# File 'lib/chewy/query.rb', line 849 def types *params chain { criteria.update_types params } end |
#types!(*params) ⇒ Object
Acts the same way as types, but cleans up previously set types
UsersIndex.types(:admin).types!(:manager)
# => {body: {query: {filtered: {
query: {...},
filter: {type: {value: 'manager'}}
}}}}
861 862 863 |
# File 'lib/chewy/query.rb', line 861 def types! *params chain { criteria.update_types params, purge: true } end |