Commit 87858fcd822700794815819576a4354e87cf9716

Authored by Andrew Kane
2 parents f8714d22 0337e063

Merge branch 'master' of https://github.com/richardking/searchkick into richardking-master

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 &lt; Minitest::Test @@ -101,6 +101,16 @@ class TestBoost &lt; 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