Commit 87858fcd822700794815819576a4354e87cf9716
Exists in
master
and in
21 other branches
Merge branch 'master' of https://github.com/richardking/searchkick into richardking-master
Showing
3 changed files
with
51 additions
and
3 deletions
Show diff stats
lib/searchkick/query.rb
... | ... | @@ -167,14 +167,17 @@ module Searchkick |
167 | 167 | custom_filters = [] |
168 | 168 | |
169 | 169 | boost_by = options[:boost_by] || {} |
170 | + | |
170 | 171 | if boost_by.is_a?(Array) |
171 | - boost_by = Hash[boost_by.map { |f| [f, {factor: 1}] }] | |
172 | + boost_by_sum = Hash[boost_by.map { |f| [f, {factor: 1}] }] | |
173 | + elsif boost_by.is_a?(Hash) | |
174 | + boost_by_multiply, boost_by_sum = boost_by.partition { |k,v| v[:boost_mode] == "multiply" }.map{|i| Hash[i] } | |
172 | 175 | end |
173 | 176 | if options[:boost] |
174 | - boost_by[options[:boost]] = {factor: 1} | |
177 | + boost_by_sum[options[:boost]] = {factor: 1} | |
175 | 178 | end |
176 | 179 | |
177 | - boost_by.each do |field, value| | |
180 | + boost_by_sum.each do |field, value| | |
178 | 181 | script_score = |
179 | 182 | if below12 |
180 | 183 | {script_score: {script: "#{value[:factor].to_f} * log(doc['#{field}'].value + 2.718281828)"}} |
... | ... | @@ -191,6 +194,28 @@ module Searchkick |
191 | 194 | }.merge(script_score) |
192 | 195 | end |
193 | 196 | |
197 | + if boost_by_multiply | |
198 | + multiply_filters = [] | |
199 | + | |
200 | + boost_by_multiply.each do |field, value| | |
201 | + script_score = | |
202 | + if below12 | |
203 | + {script_score: {script: "#{value[:factor].to_f} * doc['#{field}'].value"}} | |
204 | + else | |
205 | + value[:factor] ||= 1 | |
206 | + {field_value_factor: {field: field, factor: value[:factor].to_f}} | |
207 | + end | |
208 | + | |
209 | + multiply_filters << { | |
210 | + filter: { | |
211 | + exists: { | |
212 | + field: field | |
213 | + } | |
214 | + } | |
215 | + }.merge(script_score) | |
216 | + end | |
217 | + end | |
218 | + | |
194 | 219 | boost_where = options[:boost_where] || {} |
195 | 220 | if options[:user_id] && personalize_field |
196 | 221 | boost_where[personalize_field] = options[:user_id] |
... | ... | @@ -238,6 +263,16 @@ module Searchkick |
238 | 263 | } |
239 | 264 | end |
240 | 265 | |
266 | + if multiply_filters && multiply_filters.any? | |
267 | + payload = { | |
268 | + function_score: { | |
269 | + functions: multiply_filters, | |
270 | + query: payload, | |
271 | + score_mode: "multiply" | |
272 | + } | |
273 | + } | |
274 | + end | |
275 | + | |
241 | 276 | payload = { |
242 | 277 | query: payload, |
243 | 278 | size: per_page, | ... | ... |
test/boost_test.rb
... | ... | @@ -101,6 +101,16 @@ class TestBoost < Minitest::Test |
101 | 101 | assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_by: {orders_count: {factor: 10}} |
102 | 102 | end |
103 | 103 | |
104 | + def test_multiply_by | |
105 | + store [ | |
106 | + {name: "Tomato A", found_rate: 0.9}, | |
107 | + {name: "Tomato B"}, | |
108 | + {name: "Tomato C", found_rate: 0.5} | |
109 | + ] | |
110 | + | |
111 | + assert_order "tomato", ["Tomato B", "Tomato A", "Tomato C"], boost_by: {found_rate: {factor: 1, boost_mode: "multiply"}} | |
112 | + end | |
113 | + | |
104 | 114 | def test_boost_where |
105 | 115 | store [ |
106 | 116 | {name: "Tomato A"}, | ... | ... |
test/test_helper.rb
... | ... | @@ -51,6 +51,7 @@ if defined?(Mongoid) |
51 | 51 | field :in_stock, type: Boolean |
52 | 52 | field :backordered, type: Boolean |
53 | 53 | field :orders_count, type: Integer |
54 | + field :found_rate, type: BigDecimal | |
54 | 55 | field :price, type: Integer |
55 | 56 | field :color |
56 | 57 | field :latitude, type: BigDecimal |
... | ... | @@ -90,6 +91,7 @@ elsif defined?(NoBrainer) |
90 | 91 | field :in_stock, type: Boolean |
91 | 92 | field :backordered, type: Boolean |
92 | 93 | field :orders_count, type: Integer |
94 | + field :found_rate | |
93 | 95 | field :price, type: Integer |
94 | 96 | field :color, type: String |
95 | 97 | field :latitude |
... | ... | @@ -139,6 +141,7 @@ else |
139 | 141 | t.boolean :in_stock |
140 | 142 | t.boolean :backordered |
141 | 143 | t.integer :orders_count |
144 | + t.decimal :found_rate | |
142 | 145 | t.integer :price |
143 | 146 | t.string :color |
144 | 147 | t.decimal :latitude, precision: 10, scale: 7 | ... | ... |