Class: Stretchy::Clauses::WhereClause

Inherits:
Base
  • Object
show all
Defined in:
lib/stretchy/clauses/where_clause.rb

Overview

A Where clause inherits the same state as any clause, but has a few possible states to transition to. You can call #range and #geo to add their respective filters, or you can transition to the inverted state via #not, or the should state via #should

STATES:

  • inverted: any filters added in this state will be inverted, ie the document must NOT match said filters.
  • should: any filters added in this state will be applied to a should block. Documents which do not match these filters will be returned, but documents which do match will have a higher relevance score.

Constant Summary

Constants inherited from Base

Base::DEFAULT_LIMIT, Base::DEFAULT_OFFSET

Instance Attribute Summary

Attributes inherited from Base

#aggregate_builder, #boost_builder, #index_name, #inverse, #match_builder, #type, #where_builder

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#boost, #explain, #get_explain, #get_limit, #get_offset, #inverse?, #limit, #match, #offset, #query_results, #to_search, #where

Constructor Details

#initialize(base, options = {}) ⇒ WhereClause

Options passed to the initializer will be interpreted as filters to be added to the query. This is similar to ActiveRecord's where method.

Examples:

Apply ActiveRecord-like filters

query.where(
  string_field: "string",
  must_not_exist: nil,
  in_range: 27..33,
  included_in: [47, 23, 86]
)

Parameters:

  • base (Base)

    Used to intialize the new state from the previous clause

  • options (defaults to: {})

    = {} [Hash] filters to be applied to the new state

Options Hash (options):

  • :inverted (true, false) — default: nil

    Whether the new state is inverted

  • :should (true, false) — default: nil

    Whether the new state is should

See Also:



61
62
63
64
65
66
# File 'lib/stretchy/clauses/where_clause.rb', line 61

def initialize(base, options = {})
  super(base)
  @inverse = options.delete(:inverse)
  @should  = options.delete(:should)
  add_params(options)
end

Class Method Details

.tmp(options = {}) ⇒ WhereClause

Creates a temporary context by initializing a new Base object. Used primarily in BoostWhereClause

Parameters:

  • options (defaults to: {})

    = {} [Hash] Options to filter on

Returns:

  • (WhereClause)

    A clause outside the main query context



33
34
35
# File 'lib/stretchy/clauses/where_clause.rb', line 33

def self.tmp(options = {})
  self.new(Base.new, options)
end

Instance Method Details

#geo(field, options = {}) ⇒ self

Adds a geo distance filter to the current context. Documents must have a geo_point field that is within the specified distance of the passed parameters.

Examples:

Searching by distance from a point

query.where.geo(:coords,
  distance: '27km',
  lat: 33.3,
  lng: 29.2
)

Parameters:

  • field (String, Symbol)

    The field this filter will be applied to.

  • options (defaults to: {})

    = {} [Hash] Options for the geo distance filter

Options Hash (options):

  • :distance (String) — default: nil

    The maximum distance from the specified origin. Use an Elastic distance format such as '21mi' or '37km'

  • :lat (Float) — default: nil

    The latitude of the origin point. Can also be specified as :latitude

  • :lng (Float) — default: nil

    The longitude of the origin point. Can also be specified as :lon or :longitude

Returns:

  • (self)

    query state with geo distance filter applied



124
125
126
127
128
129
130
# File 'lib/stretchy/clauses/where_clause.rb', line 124

def geo(field, options = {})
  get_storage(:geos)[field] = {
    distance:  options[:distance],
    geo_point: Stretchy::Types::GeoPoint.new(options)
  }
  self
end

#not(options = {}) ⇒ WhereClause

Switches current state to inverted. Options passed here are equivalent to those passed to #initialize, except documents must not match these filters.

Can be chained with #should to produce inverted should queries

Examples:

Inverting filters

query.where.not(
  must_exist: nil,
  not_matching: "this string",
  not_in: [45, 67, 99],
  not_in_range: 89..23
)

Inverted should filters

query.should.not(
  match_field: [:these, "options"]
)

Parameters:

  • options (defaults to: {})

    = {} [Hash] Options to filter on

Returns:

  • (WhereClause)

    inverted query state with not filters applied.



155
156
157
# File 'lib/stretchy/clauses/where_clause.rb', line 155

def not(options = {})
  self.class.new(self, options.merge(inverse: true, should: should?))
end

#range(field, options = {}) ⇒ self

Add a range filter to the current context. While you can pass a Range object to Base#where, this allows you to specify an open-ended range, such as only specifying the minimum or maximum value.

Examples:

Adding a range filter

query.where.range(:my_range_field,
  min: 33,
  exclusive: true
)

Parameters:

  • field (String, Symbol)

    The field to filter with this range

  • options (defaults to: {})

    = {} [Hash] Options for the range

Options Hash (options):

  • :min (Numeric) — default: nil

    Minimum. Ranges are inclusive by default

  • :max (Numeric) — default: nil

    Maximum. Ranges are inclusive by default

  • :exclusive (true, false) — default: nil

    Overrides default and makes the range exclusive - equivalent to passing both :exclusive_min and :exclusive_max

  • :exclusive_min (true, false) — default: nil

    Overrides default and makes the minimum exclusive

  • :exclusive_max (true, false) — default: nil

    Overrides default and makes the maximum exclusive

Returns:

  • (self)

    query state with range filter applied



98
99
100
101
# File 'lib/stretchy/clauses/where_clause.rb', line 98

def range(field, options = {})
  get_storage(:ranges)[field] = Stretchy::Types::Range.new(options)
  self
end

#should(options = {}) ⇒ WhereClause

Switches the current state to should. Options passed here are equivalent to those passed to #initialize, except documents which do not match are still returned with a lower score than documents which do match.

Can be chained with #not to produce inverted should queries

Examples:

Specifying should options

query.should(
  field: [99, 27]
)

Inverted should options

query.should.not(
  exists_field: nil
) 

Parameters:

  • options (defaults to: {})

    = {} [Hash] Options to filter on

Returns:

  • (WhereClause)

    should query state with should filters applied



180
181
182
# File 'lib/stretchy/clauses/where_clause.rb', line 180

def should(options = {})
  self.class.new(self, options.merge(should: true))
end

#should?true, false

Accessor for @should

Returns:

  • (true, false)

    @should



72
73
74
# File 'lib/stretchy/clauses/where_clause.rb', line 72

def should?
  !!@should
end

#to_boost(weight = nil) ⇒ Boosts::FilterBoost

Converts the current context into a boost to be passed into a FunctionScoreQuery.

Parameters:

  • weight (defaults to: nil)

    = nil [Numeric] A weight for the FunctionScoreQuery

Returns:



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/stretchy/clauses/where_clause.rb', line 191

def to_boost(weight = nil)
  weight ||= Stretchy::Boosts::FilterBoost::DEFAULT_WEIGHT
  
  if @match_builder.any? && @where_builder.any?
    Stretchy::Boosts::FilterBoost.new(
      filter: Stretchy::Filters::QueryFilter.new(
        Stretchy::Queries::FilteredQuery.new(
          query:  @match_builder.build,
          filter: @where_builder.build
        )
      ),
      weight: weight
    )
  
  elsif @match_builder.any?
    Stretchy::Boosts::FilterBoost.new(
      filter: Stretchy::Filters::QueryFilter.new(
        @match_builder.build
      ),
      weight: weight
    )

  elsif @where_builder.any?
    Stretchy::Boosts::FilterBoost.new(
      filter: @where_builder.build,
      weight: weight
    )
  end
end