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.

Author:

  • [atevans]

Instance Attribute Summary

Attributes inherited from Base

#base

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#aggregations, #boost, #explain, #fields, #get_aggregations, #get_explain, #get_fields, #get_limit, #get_offset, #get_page, #inverse?, #limit, #match, #offset, #page, #query_results, #where

Constructor Details

#initialize(base = nil, 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) (defaults to: nil)

    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:



65
66
67
68
# File 'lib/stretchy/clauses/where_clause.rb', line 65

def initialize(base = nil, options = {})
  super(base)
  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
36
37
38
39
# File 'lib/stretchy/clauses/where_clause.rb', line 33

def self.tmp(options = {})
  if options.delete(:inverse)
    self.new(Builders::ShellBuilder.new).not(options)
  else
    self.new(Builders::ShellBuilder.new, options)
  end
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



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

def geo(field, options = {})
  distance = options[:distance]
  opts = options.merge(inverse: inverse?, should: should?)
  base.where_builder.add_geo(field, distance, opts)
  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.



156
157
158
159
160
# File 'lib/stretchy/clauses/where_clause.rb', line 156

def not(options = {})
  @inverse = true
  add_params(options)
  self
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



100
101
102
103
# File 'lib/stretchy/clauses/where_clause.rb', line 100

def range(field, options = {})
  base.where_builder.add_range(field, options.merge(inverse: inverse?, should: should?))
  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



183
184
185
186
187
188
# File 'lib/stretchy/clauses/where_clause.rb', line 183

def should(options = {})
  @inverse = false
  @should  = true
  add_params(options)
  self
end

#should?true, false

Accessor for @should

Returns:

  • (true, false)

    @should



74
75
76
# File 'lib/stretchy/clauses/where_clause.rb', line 74

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:



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/stretchy/clauses/where_clause.rb', line 197

def to_boost(weight = nil)
  weight ||= Stretchy::Boosts::FilterBoost::DEFAULT_WEIGHT

  if base.match_builder.any? && base.where_builder.any?
    Stretchy::Boosts::FilterBoost.new(
      filter: Stretchy::Filters::QueryFilter.new(
        Stretchy::Queries::FilteredQuery.new(
          query:  base.match_builder.to_query,
          filter: base.where_builder.to_filter
        )
      ),
      weight: weight
    )
  
  elsif base.match_builder.any?
    Stretchy::Boosts::FilterBoost.new(
      filter: Stretchy::Filters::QueryFilter.new(
        base.match_builder.to_query
      ),
      weight: weight
    )

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