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,14 +167,17 @@ module Searchkick | ||
167 | custom_filters = [] | 167 | custom_filters = [] |
168 | 168 | ||
169 | boost_by = options[:boost_by] || {} | 169 | boost_by = options[:boost_by] || {} |
170 | + | ||
170 | if boost_by.is_a?(Array) | 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 | end | 175 | end |
173 | if options[:boost] | 176 | if options[:boost] |
174 | - boost_by[options[:boost]] = {factor: 1} | 177 | + boost_by_sum[options[:boost]] = {factor: 1} |
175 | end | 178 | end |
176 | 179 | ||
177 | - boost_by.each do |field, value| | 180 | + boost_by_sum.each do |field, value| |
178 | script_score = | 181 | script_score = |
179 | if below12 | 182 | if below12 |
180 | {script_score: {script: "#{value[:factor].to_f} * log(doc['#{field}'].value + 2.718281828)"}} | 183 | {script_score: {script: "#{value[:factor].to_f} * log(doc['#{field}'].value + 2.718281828)"}} |
@@ -191,6 +194,28 @@ module Searchkick | @@ -191,6 +194,28 @@ module Searchkick | ||
191 | }.merge(script_score) | 194 | }.merge(script_score) |
192 | end | 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 | boost_where = options[:boost_where] || {} | 219 | boost_where = options[:boost_where] || {} |
195 | if options[:user_id] && personalize_field | 220 | if options[:user_id] && personalize_field |
196 | boost_where[personalize_field] = options[:user_id] | 221 | boost_where[personalize_field] = options[:user_id] |
@@ -238,6 +263,16 @@ module Searchkick | @@ -238,6 +263,16 @@ module Searchkick | ||
238 | } | 263 | } |
239 | end | 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 | payload = { | 276 | payload = { |
242 | query: payload, | 277 | query: payload, |
243 | size: per_page, | 278 | size: per_page, |
test/boost_test.rb
@@ -101,6 +101,16 @@ class TestBoost < Minitest::Test | @@ -101,6 +101,16 @@ class TestBoost < Minitest::Test | ||
101 | assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_by: {orders_count: {factor: 10}} | 101 | assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_by: {orders_count: {factor: 10}} |
102 | end | 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 | def test_boost_where | 114 | def test_boost_where |
105 | store [ | 115 | store [ |
106 | {name: "Tomato A"}, | 116 | {name: "Tomato A"}, |
test/test_helper.rb
@@ -51,6 +51,7 @@ if defined?(Mongoid) | @@ -51,6 +51,7 @@ if defined?(Mongoid) | ||
51 | field :in_stock, type: Boolean | 51 | field :in_stock, type: Boolean |
52 | field :backordered, type: Boolean | 52 | field :backordered, type: Boolean |
53 | field :orders_count, type: Integer | 53 | field :orders_count, type: Integer |
54 | + field :found_rate, type: BigDecimal | ||
54 | field :price, type: Integer | 55 | field :price, type: Integer |
55 | field :color | 56 | field :color |
56 | field :latitude, type: BigDecimal | 57 | field :latitude, type: BigDecimal |
@@ -90,6 +91,7 @@ elsif defined?(NoBrainer) | @@ -90,6 +91,7 @@ elsif defined?(NoBrainer) | ||
90 | field :in_stock, type: Boolean | 91 | field :in_stock, type: Boolean |
91 | field :backordered, type: Boolean | 92 | field :backordered, type: Boolean |
92 | field :orders_count, type: Integer | 93 | field :orders_count, type: Integer |
94 | + field :found_rate | ||
93 | field :price, type: Integer | 95 | field :price, type: Integer |
94 | field :color, type: String | 96 | field :color, type: String |
95 | field :latitude | 97 | field :latitude |
@@ -139,6 +141,7 @@ else | @@ -139,6 +141,7 @@ else | ||
139 | t.boolean :in_stock | 141 | t.boolean :in_stock |
140 | t.boolean :backordered | 142 | t.boolean :backordered |
141 | t.integer :orders_count | 143 | t.integer :orders_count |
144 | + t.decimal :found_rate | ||
142 | t.integer :price | 145 | t.integer :price |
143 | t.string :color | 146 | t.string :color |
144 | t.decimal :latitude, precision: 10, scale: 7 | 147 | t.decimal :latitude, precision: 10, scale: 7 |