Class: ChewyQuery::Builder::Filters

Inherits:
Object
  • Object
show all
Defined in:
lib/chewy_query/builder/filters.rb

Overview

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

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

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Filters.



31
32
33
34
# File 'lib/chewy_query/builder/filters.rb', line 31

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

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object

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

builder.filter{ name == 'Name' } == builder.filter(term: {name: 'Name'}) # => true
builder.filter{ name? } == builder.filter(exists: {term: 'name'}) # => true
builder.filter{ name(execution: :bool) == ['Name1', 'Name2'] } ==
  builder.filter(terms: {name: ['Name1', 'Name2'], execution: :bool}) # => true

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

builder.filter{ article.title =~ 'Hello' }
builder.filter{ article.tags? }


203
204
205
206
207
208
209
210
# File 'lib/chewy_query/builder/filters.rb', line 203

def method_missing(method, *args, &block)
  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.



222
223
224
# File 'lib/chewy_query/builder/filters.rb', line 222

def __render__
  __result__.__render__ # haha, wtf?
end

#__result__Object

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



215
216
217
# File 'lib/chewy_query/builder/filters.rb', line 215

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.

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

Supports block for getting field name from the outer scope

def field
  :name
end

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


65
66
67
68
# File 'lib/chewy_query/builder/filters.rb', line 65

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.

builder.filter{ has_child('user').filter(term: {role: 'Admin'}) }
builder.filter{ has_child('user').filter{ role == 'Admin' } }
builder.filter{ has_child('user').query(match: {name: 'borogoves'}) }

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

builder.filter do
  has_child('user')
    .filter{ name: 'Peter' }
    .query(match: {name: 'Peter'})
    .filter{ age > 42 }
    .filter_mode(:or)
end


158
159
160
# File 'lib/chewy_query/builder/filters.rb', line 158

def has_child(type)
  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.

builder.filter{ has_parent('user').filter(term: {role: 'Admin'}) }
builder.filter{ has_parent('user').filter{ role == 'Admin' } }
builder.filter{ has_parent('user').query(match: {name: 'borogoves'}) }

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

builder.filter do
  has_parent('user')
    .filter{ name: 'Peter' }
    .query(match: {name: 'Peter'})
    .filter{ age > 42 }
    .filter_mode(:or)
end


180
181
182
# File 'lib/chewy_query/builder/filters.rb', line 180

def has_parent(type)
  Nodes::HasParent.new(type, @outer)
end

#match_allObject

Just simple match_all filter.



186
187
188
# File 'lib/chewy_query/builder/filters.rb', line 186

def match_all
  Nodes::MatchAll.new
end

#o(&block) ⇒ Object

Outer scope call Block evaluates in the external context

def name
  'Friend'
end

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


45
46
47
# File 'lib/chewy_query/builder/filters.rb', line 45

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

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

Returns query filter

builder.filter{ q(query_string: {query: 'name: hello'}) }

Supports block for getting query from the outer scope

def query
  {query_string: {query: 'name: hello'}}
end

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


103
104
105
# File 'lib/chewy_query/builder/filters.rb', line 103

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

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

Supports block for getting raw filter from the outer scope

def filter
  {term: {name: 'Name'}}
end

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


122
123
124
# File 'lib/chewy_query/builder/filters.rb', line 122

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.

builder.filter{ s('doc["num1"].value > 1') }
builder.filter{ s('doc["num1"].value > param1', param1: 42) }

Supports block for getting script from the outer scope

def script
  'doc["num1"].value > param1 || 1'
end

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


85
86
87
88
89
# File 'lib/chewy_query/builder/filters.rb', line 85

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