Class: Chewy::Query::Filters

Inherits:
Object
  • Object
show all
Defined in:
lib/chewy/query/filters.rb

Overview

Context provides simplified DSL functionality for filters declaring. You can use logic operations & and | to concat expressions.

Examples:

UsersIndex.filter{ (article.title =~ /Honey/) & (age < 42) & !rate }

Instance Method Summary collapse

Constructor Details

#initialize(outer = nil, &block) ⇒ Filters

Returns a new instance of Filters.



32
33
34
35
# File 'lib/chewy/query/filters.rb', line 32

def initialize(outer = nil, &block)
  @block = block
  @outer = outer || eval('self', block.binding, __FILE__, __LINE__)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

Creates field or exists node Additional options for further expression might be passed as hash

Also field names might be chained to use dot-notation for ES field names

Examples:

UsersIndex.filter{ name == 'Name' } == UsersIndex.filter(term: {name: 'Name'}) # => true
UsersIndex.filter{ name? } == UsersIndex.filter(exists: {term: 'name'}) # => true
UsersIndex.filter{ name(execution: :bool) == ['Name1', 'Name2'] } ==
  UsersIndex.filter(terms: {name: ['Name1', 'Name2'], execution: :bool}) # => true
UsersIndex.filter{ article.title =~ 'Hello' }
UsersIndex.filter{ article.tags? }


220
221
222
223
224
225
226
227
# File 'lib/chewy/query/filters.rb', line 220

def method_missing(method, *args) # rubocop:disable Style/MethodMissing
  method = method.to_s
  if method =~ /\?\Z/
    Nodes::Exists.new method.gsub(/\?\Z/, '')
  else
    f method, *args
  end
end

Instance Method Details

#__render__Object

Renders evaluated filters. For internal usage.



239
240
241
# File 'lib/chewy/query/filters.rb', line 239

def __render__
  __result__.__render__ # haha, wtf?
end

#__result__Object

Evaluates context block, returns top node. For internal usage.



232
233
234
# File 'lib/chewy/query/filters.rb', line 232

def __result__
  instance_exec(&@block)
end

#f(name = nil, *args, &block) ⇒ Object

Returns field node Used if method_missing is not working by some reason. Additional expression options might be passed as second argument hash.

Supports block for getting field name from the outer scope

Examples:

UsersIndex.filter{ f(:name) == 'Name' } == UsersIndex.filter{ name == 'Name' } # => true
UsersIndex.filter{ f(:name, execution: :bool) == ['Name1', 'Name2'] } ==
  UsersIndex.filter{ name(execution: :bool) == ['Name1', 'Name2'] } # => true
def field
  :name
end

UsersIndex.filter{ f{ field } == 'Name' } == UsersIndex.filter{ name == 'Name' } # => true


69
70
71
72
# File 'lib/chewy/query/filters.rb', line 69

def f(name = nil, *args, &block)
  name = block ? o(&block) : name
  Nodes::Field.new name, *args
end

#has_child(type) ⇒ Object

Initializes has_child filter. Chainable interface acts the same as main query interface. You can pass plain filters or plain queries or filter with DSL block.

Filters and queries might be combined and filter_mode and query_mode are configurable:

Examples:

UsersIndex.filter{ has_child('user').filter(term: {role: 'Admin'}) }
UsersIndex.filter{ has_child('user').filter{ role == 'Admin' } }
UsersIndex.filter{ has_child('user').query(match: {name: 'borogoves'}) }
UsersIndex.filter do
  has_child('user')
    .filter{ name: 'Peter' }
    .query(match: {name: 'Peter'})
    .filter{ age > 42 }
    .filter_mode(:or)
end


171
172
173
# File 'lib/chewy/query/filters.rb', line 171

def has_child(type) # rubocop:disable Naming/PredicateName
  Nodes::HasChild.new(type, @outer)
end

#has_parent(type) ⇒ Object

Initializes has_parent filter. Chainable interface acts the same as main query interface. You can pass plain filters or plain queries or filter with DSL block.

Filters and queries might be combined and filter_mode and query_mode are configurable:

Examples:

UsersIndex.filter{ has_parent('user').filter(term: {role: 'Admin'}) }
UsersIndex.filter{ has_parent('user').filter{ role == 'Admin' } }
UsersIndex.filter{ has_parent('user').query(match: {name: 'borogoves'}) }
UsersIndex.filter do
  has_parent('user')
    .filter{ name: 'Peter' }
    .query(match: {name: 'Peter'})
    .filter{ age > 42 }
    .filter_mode(:or)
end


195
196
197
# File 'lib/chewy/query/filters.rb', line 195

def has_parent(type) # rubocop:disable Naming/PredicateName
  Nodes::HasParent.new(type, @outer)
end

#match_allObject

Just simple match_all filter.



201
202
203
# File 'lib/chewy/query/filters.rb', line 201

def match_all
  Nodes::MatchAll.new
end

#o(&block) ⇒ Object

Outer scope call Block evaluates in the external context

Examples:

def name
  'Friend'
end

UsersIndex.filter{ name == o{ name } } # => {filter: {term: {name: 'Friend'}}}


47
48
49
# File 'lib/chewy/query/filters.rb', line 47

def o(&block)
  @outer.instance_exec(&block)
end

#q(query = nil, &block) ⇒ Object

Returns query filter

Supports block for getting query from the outer scope

Examples:

UsersIndex.filter{ q(query_string: {query: 'name: hello'}) }
def query
  {query_string: {query: 'name: hello'}}
end

UsersIndex.filter{ q{ query } } == UsersIndex.filter{ q(query_string: {query: 'name: hello'}) } # => true


111
112
113
# File 'lib/chewy/query/filters.rb', line 111

def q(query = nil, &block)
  Nodes::Query.new block ? o(&block) : query
end

#r(raw = nil, &block) ⇒ Object

Returns raw expression Same as filter with arguments instead of block, but can participate in expressions

Supports block for getting raw filter from the outer scope

Examples:

UsersIndex.filter{ r(term: {name: 'Name'}) }
UsersIndex.filter{ r(term: {name: 'Name'}) & (age < 42) }
def filter
  {term: {name: 'Name'}}
end

UsersIndex.filter{ r{ filter } } == UsersIndex.filter{ r(term: {name: 'Name'}) } # => true
UsersIndex.filter{ r{ filter } } == UsersIndex.filter(term: {name: 'Name'}) # => true


132
133
134
# File 'lib/chewy/query/filters.rb', line 132

def r(raw = nil, &block)
  Nodes::Raw.new block ? o(&block) : raw
end

#s(*args, &block) ⇒ Object

Returns script filter Just script filter. Supports additional params.

Supports block for getting script from the outer scope

Examples:

UsersIndex.filter{ s('doc["num1"].value > 1') }
UsersIndex.filter{ s('doc["num1"].value > param1', param1: 42) }
def script
  'doc["num1"].value > param1 || 1'
end

UsersIndex.filter{ s{ script } } == UsersIndex.filter{ s('doc["num1"].value > 1') } # => true
UsersIndex.filter{ s(param1: 42) { script } } == UsersIndex.filter{ s('doc["num1"].value > 1', param1: 42) } # => true


91
92
93
94
95
# File 'lib/chewy/query/filters.rb', line 91

def s(*args, &block)
  params = args.extract_options!
  script = block ? o(&block) : args.first
  Nodes::Script.new script, params
end