Class: Chewy::Query
- Includes:
- Loading, Pagination, Search::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/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
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: 'Alex').limit(20) UsersIndex::User.filter{ age < 42 }.query(text: 'Alex').limit(20)
Defined Under Namespace
Modules: Compose, Loading, Nodes, Pagination Classes: Criteria, Filters
Constant Summary collapse
- DELEGATED_METHODS =
i[ explain query_mode filter_mode post_filter_mode timeout limit offset highlight min_score rescore facets script_score boost_factor weight random_score field_value_factor decay aggregations suggest none strategy query filter post_filter boost_mode score_mode order reorder only types delete_all find total total_count total_entries unlimited script_fields track_scores preference ].to_set.freeze
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 aggregations search 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 documents matching a query.
-
#exists? ⇒ Boolean
Returns true if there are at least one document that matches the query.
-
#explain(value = nil) ⇒ Object
Adds explain parameter 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_mode option value.
-
#filter_mode(value) ⇒ Object
Sets query compilation mode for search request.
-
#find(*ids) ⇒ Object
Find all documents 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 = nil, &block) ⇒ Object
Sets elasticsearch size search 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 documents.
-
#offset(value = nil, &block) ⇒ Object
Sets elasticsearch from search 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_mode option value.
-
#post_filter_mode(value) ⇒ Object
Acts the same way as
filter_mode, but used forpost_filter. -
#preference(value) ⇒ Object
Sets preference for request.
-
#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.
-
#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_fields parameter to search request.
-
#script_score(script, options = {}) ⇒ Object
Adds a script function to score the search request.
-
#search_type(value) ⇒ Object
Sets search_type for request.
-
#strategy(value = nil) ⇒ Object
Setups strategy for top-level filtered query.
-
#suggest(params = nil) ⇒ Object
Sets elasticsearch suggest search 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.
-
#track_scores(value) ⇒ Object
Elasticsearch track_scores option support.
-
#types(*params) ⇒ Object
Specify types participating in the search result Works via types filter.
-
#types!(*params) ⇒ Object
Acts the same way as types, but cleans up previously set types.
-
#unlimited ⇒ Object
Sets limit to be equal to total documents count.
-
#weight(factor, options = {}) ⇒ Object
Add a weight scoring function to the search.
Methods included from Search::Scoping
Methods included from Pagination
Methods included from Loading
Constructor Details
#initialize(*indexes_or_types_and_options) ⇒ Query
Returns a new instance of Query.
34 35 36 37 38 39 40 |
# File 'lib/chewy/query.rb', line 34 def initialize(*) = . @_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.
32 33 34 |
# File 'lib/chewy/query.rb', line 32 def _indexes @_indexes end |
#_types ⇒ Object (readonly)
Returns the value of attribute _types.
32 33 34 |
# File 'lib/chewy/query.rb', line 32 def _types @_types end |
#criteria ⇒ Object (readonly)
Returns the value of attribute criteria.
32 33 34 |
# File 'lib/chewy/query.rb', line 32 def criteria @criteria end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
32 33 34 |
# File 'lib/chewy/query.rb', line 32 def 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: 'Johny') == UsersIndex.filter(term: 'Johny') # => true UsersIndex.filter(term: 'Johny') == UsersIndex.filter(term: 'Johny').to_a # => true UsersIndex.filter(term: 'Johny') == UsersIndex.filter(term: 'Winnie') # => false
50 51 52 |
# File 'lib/chewy/query.rb', line 50 def ==(other) super || other.is_a?(self.class) ? other.criteria == criteria : other == to_a end |
#_build_fqn_aggs ⇒ Object
573 574 575 576 577 578 579 580 581 582 583 584 585 |
# File 'lib/chewy/query.rb', line 573 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
561 562 563 564 565 566 567 568 569 570 571 |
# File 'lib/chewy/query.rb', line 561 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
587 588 589 590 591 592 593 |
# File 'lib/chewy/query.rb', line 587 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: {field: 'category_ids'}) # => { query: {..., aggregations: { terms: { field: 'category_ids' } } }}
547 548 549 550 551 552 553 554 555 556 557 |
# File 'lib/chewy/query.rb', line 547 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} }) # => query: { function_score: { query: { ..., functions: [{ boost_factor: 23, filter: { term: { foo: :bar } } }] } } }
405 406 407 408 |
# File 'lib/chewy/query.rb', line 405 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:
- :multiply Default 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: [ ... ]
}}}
:replace Only function result is used, query score is ignored.
:sum Query score and function score are added.
:avg Average of query and function score.
:max Max of query and function score.
:min Min of query and function score.
Default value for :boost_mode might be changed with Chewy.score_mode config option.
768 769 770 |
# File 'lib/chewy/query.rb', line 768 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}) # => query: { gauss: { query: { ..., functions: [{ gauss: { field: { origin: '11, 12', scale: '2km', offset: '5km', decay: 0.4 } }, filter: { foo: :bar } }] } } }
518 519 520 521 522 523 524 |
# File 'lib/chewy/query.rb', line 518 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 documents matching a query.
UsersIndex.delete_all UsersIndex.filter{ age <= 42 }.delete_all UsersIndex::User.delete_all UsersIndex::User.filter{ age <= 42 }.delete_all
942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 |
# File 'lib/chewy/query.rb', line 942 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 if Runtime.version >= '2.0' path = Elasticsearch::API::Utils.__pathify( Elasticsearch::API::Utils.__listify(request[:index]), Elasticsearch::API::Utils.__listify(request[:type]), '/_query' ) Chewy.client.perform_request(Elasticsearch::API::HTTP_DELETE, path, {}, request[:body]).body else Chewy.client.delete_by_query(request) end end end |
#exists? ⇒ Boolean
Returns true if there are at least one document that matches the query
PlacesIndex.query(...).filter(...).exists?
992 993 994 |
# File 'lib/chewy/query.rb', line 992 def exists? search_type(:count).total > 0 end |
#explain(value = nil) ⇒ Object
Adds explain parameter to search request.
UsersIndex.filter(term: 'Johny').explain UsersIndex.filter(term: 'Johny').explain(true) UsersIndex.filter(term: '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: 'Johny').explain.first._explanation # => ...
66 67 68 |
# File 'lib/chewy/query.rb', line 66 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: {field: 'tags'}).facets(ages: {field: 'age'}) # => { query: {..., facets: {terms: {field: 'tags'}, ages: {field: 'age'}} }}
If called parameterless - returns result facets from ES performing request. Returns empty hash if no facets was requested or resulted.
357 358 359 360 361 362 363 364 |
# File 'lib/chewy/query.rb', line 357 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}) # => query: { function_score: { query: { ..., functions: [{ field_value_factor: { field: :boost, factor: 1.2, modifier: :sqrt }, filter: { foo: :bar } }] } } }
482 483 484 485 |
# File 'lib/chewy/query.rb', line 482 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: 'Johny').filter(range: {lte: 42}) UsersIndex::User.filter(term: 'Johny').filter(range: {lte: 42}) UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 } # => {query: {filtered: { query: {..., filter: [{term: {name: 'Johny'}, {age: {lte: 42}}]} }}}}
If only one filter was specified, it will become a result filter as is, without joining.
UsersIndex.filter(term: 'Johny') # => {query: {filtered: { query: {..., filter: {name: 'Johny'} }}}}
699 700 701 702 |
# File 'lib/chewy/query.rb', line 699 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:
- :and Default value. Filter compiles into an and filter.
Ex:
UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 }
# => {body: {query: {filtered: {
query: {...},
filter: {and: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}
}}}}
- :or Filter compiles into an or filter.
Ex:
UsersIndex.filter{ name == 'Johny' }.filter{ age <= 42 }.filter_mode(:or)
# => {body: {query: {filtered: {
query: {...},
filter: {or: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}
}}}}
- :must Filter compiles into a bool must filter.
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}}}]}}
}}}}
- :should Filter compiles into a bool should filter.
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_match value (1, '2', '75%') Filter compiles into bool should filter with minimum_should_match set.
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%'
222 223 224 |
# File 'lib/chewy/query.rb', line 222 def filter_mode(value) chain { criteria. filter_mode: value } end |
#find(*ids) ⇒ Object
Find all documents 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
981 982 983 984 985 986 |
# File 'lib/chewy/query.rb', line 981 def find(*ids) results = chain { criteria. simple: true }.filter { _id == ids.flatten }.to_a raise Chewy::DocumentNotFound, "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: { ... })
316 317 318 |
# File 'lib/chewy/query.rb', line 316 def highlight(value) chain { criteria. highlight: value } end |
#limit(value = nil, &block) ⇒ Object
Sets elasticsearch size search request param Default value is set in the elasticsearch and is 10.
UsersIndex.filter{ name == 'Johny' }.limit(100) # => { query: {..., size: 100 }}
296 297 298 |
# File 'lib/chewy/query.rb', line 296 def limit(value = nil, &block) chain { criteria. size: block || 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
931 932 933 |
# File 'lib/chewy/query.rb', line 931 def merge(other) chain { criteria.merge!(other.criteria) } end |
#min_score(value) ⇒ Object
Elasticsearch minscore option support
UsersIndex.query(...).min_score(0.5)
332 333 334 |
# File 'lib/chewy/query.rb', line 332 def min_score(value) chain { criteria. min_score: value } end |
#none ⇒ Object
Marks the criteria as having zero documents. 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: 'Johny').none.to_a # => [] UsersIndex.none.query(text: 'Johny').to_a # => []
627 628 629 |
# File 'lib/chewy/query.rb', line 627 def none chain { criteria. none: true } end |
#offset(value = nil, &block) ⇒ Object
Sets elasticsearch from search request param
UsersIndex.filter{ name == 'Johny' }.offset(300) # => { query: {..., from: 300 }}
308 309 310 |
# File 'lib/chewy/query.rb', line 308 def offset(value = nil, &block) chain { criteria. from: block || Integer(value) } end |
#only(*params) ⇒ Object
Sets search request field list
UsersIndex.only(:first_name, :last_name).only(:age) # => { query: {..., fields: ['first_name', 'last_name', 'age'] }}
844 845 846 |
# File 'lib/chewy/query.rb', line 844 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) # => { query: {..., fields: ['age'] }}
856 857 858 |
# File 'lib/chewy/query.rb', line 856 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: :asc, mode: :avg) # => { query: {..., sort: ['first_name', 'last_name', 'desc', {order: 'asc', mode: 'avg'}] }}
820 821 822 |
# File 'lib/chewy/query.rb', line 820 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: 'Johny').post_filter(range: {lte: 42}) UsersIndex::User.post_filter(term: 'Johny').post_filter(range: {lte: 42}) UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 } # => { post_filter: {and: [{term: {name: 'Johny'}, {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: 'Johny') # => { post_filter: {term: {name: 'Johny'} }}
730 731 732 733 |
# File 'lib/chewy/query.rb', line 730 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%')
234 235 236 |
# File 'lib/chewy/query.rb', line 234 def post_filter_mode(value) chain { criteria. post_filter_mode: value } end |
#preference(value) ⇒ Object
Sets preference for request. For instance, one can use preference=_primary to execute only on the primary shards.
scope = UsersIndex.preference(:_primary)
531 532 533 |
# File 'lib/chewy/query.rb', line 531 def preference(value) chain { criteria. preference: 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: 'Johny').query(range: {lte: 42}) UsersIndex::User.query(text: 'Johny').query(range: {lte: 42}) # => { query: {bool: {must: [{text: {name: 'Johny'}, {age: {lte: 42}}]}} }}
If only one query was specified, it will become a result query as is, without joining.
UsersIndex.query(text: 'Johny') # => { query: {text: {name: 'Johny'} }}
667 668 669 |
# File 'lib/chewy/query.rb', line 667 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:
- :must Default value. Query compiles into a bool must query.
Ex:
UsersIndex.query(text: {name: 'Johny'}).query(range: {age: {lte: 42}})
# => {body: {
query: {bool: {must: [{text: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}}
}}
- :should Query compiles into a bool should query.
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_match value (1, '2', '75%') Query compiles into a bool should query with minimum_should_match set.
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_max Query compiles into a dis_max query.
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_max query with tie_breaker option 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%'
150 151 152 |
# File 'lib/chewy/query.rb', line 150 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}) # => query: { function_score: { query: { ..., functions: [{ random_score: { seed: 23 }, filter: { foo: :bar } }] } } }
451 452 453 454 |
# File 'lib/chewy/query.rb', line 451 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: :asc, mode: :avg) # => { query: {..., sort: [{order: 'asc', mode: 'avg'}] }}
832 833 834 |
# File 'lib/chewy/query.rb', line 832 def reorder(*params) chain { criteria.update_sort params, purge: true } end |
#rescore(value) ⇒ Object
Elasticsearch rescore query option support
UsersIndex.query(...).rescore(query: { ... })
324 325 326 |
# File 'lib/chewy/query.rb', line 324 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:
- :multiply Default value. Scores are multiplied.
Ex:
UsersIndex.score_mode('multiply').script_score('doc['boost'].value')
# => {body: {query: function_score: {
query: {...},
score_mode: 'multiply',
functions: [ ... ]
}}}
:sum Scores are summed.
:avg Scores are averaged.
:first The first function that has a matching filter is applied.
:max Maximum score is used.
:min Minimum score is used
Default value for :score_mode might be changed with Chewy.score_mode config option.
Chewy.score_mode = :first
808 809 810 |
# File 'lib/chewy/query.rb', line 808 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)" } )
80 81 82 |
# File 'lib/chewy/query.rb', line 80 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 }) # => query: { function_score: { query: { ..., functions: [{ script_score: { script: "doc['boost'].value * modifier", params: { modifier: 2 } } } }] } } }
383 384 385 386 |
# File 'lib/chewy/query.rb', line 383 def script_score(script, = {}) scoring = {script_score: {script: script}.merge()} chain { criteria.update_scores scoring } end |
#search_type(value) ⇒ Object
Sets search_type for request. For instance, one can use search_type=count to fetch only total count of documents or to fetch only aggregations without fetching documents.
scope = UsersIndex.search_type(:count) scope.count == 0 # no documents 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']
918 919 920 |
# File 'lib/chewy/query.rb', line 918 def search_type(value) chain { criteria. search_type: value } 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' } } }}
641 642 643 |
# File 'lib/chewy/query.rb', line 641 def strategy(value = nil) chain { criteria. strategy: value } end |
#suggest(params = nil) ⇒ Object
Sets elasticsearch suggest search request param
UsersIndex.suggest(name: 'Joh', term: {field: 'name'}) # => { query: {..., suggest: { text: 'Joh', term: { field: 'name' } } }}
608 609 610 611 612 613 614 |
# File 'lib/chewy/query.rb', line 608 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
1024 1025 1026 |
# File 'lib/chewy/query.rb', line 1024 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.
283 284 285 |
# File 'lib/chewy/query.rb', line 283 def timeout(value) chain { criteria. timeout: value } end |
#took ⇒ Object
Returns request total time elapsed as reported by elasticsearch
UsersIndex.query(...).filter(...).took
1010 1011 1012 |
# File 'lib/chewy/query.rb', line 1010 def took _response['took'] end |
#track_scores(value) ⇒ Object
Elasticsearch track_scores option support
UsersIndex.query(...).track_scores(true)
340 341 342 |
# File 'lib/chewy/query.rb', line 340 def track_scores(value) chain { criteria. track_scores: value } 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 } # => {query: {filtered: { query: {..., filter: [ {or: [ {type: {value: 'admin'}, {value: 'manager'} ]}, {name: 'Johny'}, {age: {lte: 42}} ]} }}}}
UsersIndex.types(:admin, :manager).filters{ name == 'Johny' }.filters{ age <= 42 }.filter_mode(:or) # => {query: {filtered: { query: {..., filter: [ {or: [ {type: {value: 'admin'}, {value: 'manager'} ]}, [ {term: {name: 'Johny'}, {age: {lte: 42}} ]} ]} }}}}
892 893 894 |
# File 'lib/chewy/query.rb', line 892 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) # => {query: {filtered: { query: {..., filter: {value: 'manager'} }}}}
904 905 906 |
# File 'lib/chewy/query.rb', line 904 def types!(*params) chain { criteria.update_types params, purge: true } end |
#unlimited ⇒ Object
Sets limit to be equal to total documents count
PlacesIndex.query(...).filter(...).unlimited
1001 1002 1003 1004 |
# File 'lib/chewy/query.rb', line 1001 def unlimited count_query = search_type(:count) offset(0).limit { count_query.total } end |
#weight(factor, options = {}) ⇒ Object
Add a weight scoring function to the search. 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 weight as well.
UsersIndex.weight(23, filter: { term: { foo: :bar} }) # => query: { function_score: { query: { ..., functions: [{ weight: 23, filter: { term: { foo: :bar } } }] } } }
427 428 429 430 |
# File 'lib/chewy/query.rb', line 427 def weight(factor, = {}) scoring = .merge(weight: factor.to_i) chain { criteria.update_scores scoring } end |