Module: Stretchy::Factory

Defined in:
lib/stretchy/factory.rb

Constant Summary collapse

DEFAULT_WEIGHT =
1.5
DEFAULT_SLOP =
50
BOOST_OPTIONS =
[
  :filter,
  :function,
  :weight
]
FUNCTION_SCORE_OPTIONS =
[
  :boost,
  :max_boost,
  :score_mode,
  :boost_mode,
  :min_score
]

Class Method Summary collapse

Class Method Details

.context_nodes(params, context = default_context) ⇒ Object



60
61
62
63
64
65
66
67
68
69
# File 'lib/stretchy/factory.rb', line 60

def context_nodes(params, context = default_context)
  # binding.pry
  if context[:boost]
    params_to_boost(params, context)
  elsif context[:filter] && !context[:query]
    params_to_filters(dotify_params(params, context), context)
  else
    params_to_queries(dotify_params(params, context), context)
  end
end

.decay_function_node(params = {}, context = default_context) ⇒ Object



186
187
188
189
190
191
192
# File 'lib/stretchy/factory.rb', line 186

def decay_function_node(params = {}, context = default_context)
  boost_params        = extract_boost_params!(params)
  context[:fn_score]  = extract_function_score_options!(params)
  decay_fn            = params.delete(:decay_function)
  field               = params.delete(:field)
  Node.new({decay_fn => { field => params}}.merge(boost_params), context)
end

.default_contextObject



21
22
23
# File 'lib/stretchy/factory.rb', line 21

def default_context
  {}
end

.dotify_params(params, context) ⇒ Object



35
36
37
38
39
40
41
# File 'lib/stretchy/factory.rb', line 35

def dotify_params(params, context)
  if context[:nested]
    Utils.nestify(params)
  else
    Utils.dotify(params)
  end
end

.extract_boost_params!(params) ⇒ Object



25
26
27
28
29
# File 'lib/stretchy/factory.rb', line 25

def extract_boost_params!(params)
  boost_params = Utils.extract_options!(params, BOOST_OPTIONS)
  boost_params = {weight: DEFAULT_WEIGHT} unless boost_params.any?
  boost_params
end

.extract_function_score_options!(params) ⇒ Object



31
32
33
# File 'lib/stretchy/factory.rb', line 31

def extract_function_score_options!(params)
  Utils.extract_options!(params, FUNCTION_SCORE_OPTIONS)
end

.field_value_function_node(params = {}, context = default_context) ⇒ Object



172
173
174
175
176
# File 'lib/stretchy/factory.rb', line 172

def field_value_function_node(params = {}, context = default_context)
  context[:fn_score] = extract_function_score_options!(params)
  boost_params       = extract_boost_params!(params)
  Node.new(boost_params.merge(field_value_factor: params), context)
end

.fulltext_nodes_from_string(params, context = default_context) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/stretchy/factory.rb', line 130

def fulltext_nodes_from_string(params, context = default_context)
  subcontext = context.merge(query: true)
  nodes = [raw_node({
    match: {
      _all: {
        query: params,
        minimum_should_match: 1
      }
    }
  }, subcontext)]

  subcontext = subcontext.merge(should: true)
  nodes << Factory.raw_node({
    match_phrase: {
      _all: {
        query: params,
        slop:  DEFAULT_SLOP
      }
    }
  }, subcontext)

  nodes
end

.geo_distance_node(params = {}, context = default_context) ⇒ Object



167
168
169
# File 'lib/stretchy/factory.rb', line 167

def geo_distance_node(params = {}, context = default_context)
  Node.new({geo_distance: params}, context)
end

.more_like_node(params = {}, context = default_context) ⇒ Object



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

def more_like_node(params = {}, context = default_context)
  Node.new({more_like_this: params}, context)
end

.nested(params, path, context = default_context) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/stretchy/factory.rb', line 115

def nested(params, path, context = default_context)
  nodes = if context[:filter] && !context[:query]
    params_to_filters(params, context)
  else
    params_to_queries(params, context)
  end
  json  = AndCollector.new(nodes, context).json

  Node.new({nested: {
    path:   path,
    query:  json
  }}, context)
end

.params_to_boost(params, context = default_context) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/stretchy/factory.rb', line 71

def params_to_boost(params, context = default_context)
  boost_params        = extract_boost_params!(params)
  context[:fn_score]  = extract_function_score_options!(params)
  subcontext          = context.merge(boost: nil)
  nodes               = context_nodes(params, subcontext)
  collector           = AndCollector.new(nodes, subcontext)

  Node.new(boost_params.merge(filter: collector.json), context)
end

.params_to_filters(params, context = default_context) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/stretchy/factory.rb', line 100

def params_to_filters(params, context = default_context)
  params.map do |field, val|
    case val
    when Range
      Node.new({range: {field => {gte: val.min, lte: val.max}}}, context)
    when nil
      Node.new({missing: {field: field}}, context)
    when Hash
      nested(val, field, context)
    else
      Node.new({terms: {field => Array(val)}}, context)
    end
  end
end

.params_to_queries(params, context = default_context) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/stretchy/factory.rb', line 81

def params_to_queries(params, context = default_context)
  params.map do |field, val|
    case val
    when Array
      Node.new({match: {
        field => {query: val.join(' '), :operator => :or}
      }}, context)
    when Range
      Node.new({range: {
        field => {gte: val.min, lte: val.max}
      }}, context)
    when Hash
      nested(val, field, context)
    else
      Node.new({match: {field => val}}, context)
    end
  end
end

.random_score_function_node(params, context = default_context) ⇒ Object



179
180
181
182
183
# File 'lib/stretchy/factory.rb', line 179

def random_score_function_node(params, context = default_context)
  json          = {random_score: {seed: params[:seed]}}
  json[:weight] = params[:weight] if params[:weight]
  Node.new(json, context)
end

.range_node(params = {}, context = default_context) ⇒ Object



162
163
164
# File 'lib/stretchy/factory.rb', line 162

def range_node(params = {}, context = default_context)
  Node.new({range: params}, context)
end

.raw_boost_node(params, context) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/stretchy/factory.rb', line 51

def raw_boost_node(params, context)
  boost_params       = extract_boost_params!(params)
  context[:fn_score] = extract_function_score_options!(params)
  context[:boost]    = true
  context[:filter]   = true
  json = context[:query] ? {query: params} : params
  Node.new(boost_params.merge(filter: json), context)
end

.raw_node(params, context) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/stretchy/factory.rb', line 43

def raw_node(params, context)
  if context[:boost]
    raw_boost_node(params, context)
  else
    Node.new(params, context)
  end
end