Commit efacf2592151a25c3b820cb4d910bb14119af6f9
1 parent
23e4261f
Exists in
master
and in
21 other branches
Added boost_by and boost_where options
Showing
4 changed files
with
58 additions
and
18 deletions
Show diff stats
CHANGELOG.md
README.md
... | ... | @@ -116,10 +116,20 @@ Limit / offset |
116 | 116 | limit: 20, offset: 40 |
117 | 117 | ``` |
118 | 118 | |
119 | -Boost by a field | |
119 | +### Boosting | |
120 | + | |
121 | +Boost by the value of a field | |
122 | + | |
123 | +```ruby | |
124 | +boost_by: [:orders_count] # give popular documents a little boost | |
125 | +boost_by: {orders_count: {factor: 10}} | |
126 | +``` | |
127 | + | |
128 | +Boost matching documents | |
120 | 129 | |
121 | 130 | ```ruby |
122 | -boost: "orders_count" # give popular documents a little boost | |
131 | +boost_where: {user_id: 1} | |
132 | +boost_where: {user_id: {value: 1, factor: 100}} | |
123 | 133 | ``` |
124 | 134 | |
125 | 135 | ### Get Everything |
... | ... | @@ -311,22 +321,21 @@ Order results differently for each user. For example, show a user’s previousl |
311 | 321 | |
312 | 322 | ```ruby |
313 | 323 | class Product < ActiveRecord::Base |
314 | - searchkick personalize: "user_ids" | |
315 | 324 | |
316 | 325 | def search_data |
317 | 326 | { |
318 | 327 | name: name, |
319 | 328 | user_ids: orders.pluck(:user_id) # boost this product for these users |
320 | - # [4, 8, 15, 16, 23, 42] | |
321 | 329 | } |
322 | 330 | end |
331 | + | |
323 | 332 | end |
324 | 333 | ``` |
325 | 334 | |
326 | 335 | Reindex and search with: |
327 | 336 | |
328 | 337 | ```ruby |
329 | -Product.search "milk", user_id: 8 | |
338 | +Product.search "milk", boost_where: {user_id: 8} | |
330 | 339 | ``` |
331 | 340 | |
332 | 341 | ### Autocomplete | ... | ... |
lib/searchkick/query.rb
... | ... | @@ -137,36 +137,45 @@ module Searchkick |
137 | 137 | |
138 | 138 | custom_filters = [] |
139 | 139 | |
140 | + boost_by = options[:boost_by] || {} | |
141 | + if boost_by.is_a?(Array) | |
142 | + boost_by = Hash[ boost_by.map{|f| [f, {factor: 1}] } ] | |
143 | + end | |
140 | 144 | if options[:boost] |
145 | + boost_by[options[:boost]] = {factor: 1} | |
146 | + end | |
147 | + | |
148 | + boost_by.each do |field, value| | |
141 | 149 | custom_filters << { |
142 | 150 | filter: { |
143 | 151 | exists: { |
144 | - field: options[:boost] | |
152 | + field: field | |
145 | 153 | } |
146 | 154 | }, |
147 | 155 | script_score: { |
148 | - script: "log(doc['#{options[:boost]}'].value + 2.718281828)" | |
156 | + script: "#{value[:factor].to_f} * log(doc['#{field}'].value + 2.718281828)" | |
149 | 157 | } |
150 | 158 | } |
151 | 159 | end |
152 | 160 | |
161 | + boost_where = options[:boost_where] || {} | |
153 | 162 | if options[:user_id] and personalize_field |
154 | - custom_filters << { | |
155 | - filter: { | |
156 | - term: { | |
157 | - personalize_field => options[:user_id] | |
158 | - } | |
159 | - }, | |
160 | - boost_factor: 100 | |
161 | - } | |
163 | + boost_where[personalize_field] = options[:user_id] | |
162 | 164 | end |
163 | - | |
164 | 165 | if options[:personalize] |
166 | + boost_where.merge!(options[:personalize]) | |
167 | + end | |
168 | + boost_where.each do |field, value| | |
169 | + if value.is_a?(Hash) | |
170 | + value, factor = value[:value], value[:factor] | |
171 | + else | |
172 | + factor = 1000 | |
173 | + end | |
165 | 174 | custom_filters << { |
166 | 175 | filter: { |
167 | - term: options[:personalize] | |
176 | + term: {field => value} | |
168 | 177 | }, |
169 | - boost_factor: 100 | |
178 | + boost_factor: factor | |
170 | 179 | } |
171 | 180 | end |
172 | 181 | ... | ... |
test/boost_test.rb
... | ... | @@ -67,4 +67,25 @@ class TestBoost < Minitest::Unit::TestCase |
67 | 67 | assert_first "tomato", "Tomato B", personalize: {user_ids: 2} |
68 | 68 | end |
69 | 69 | |
70 | + def test_boost_by | |
71 | + store [ | |
72 | + {name: "Tomato A"}, | |
73 | + {name: "Tomato B", orders_count: 10}, | |
74 | + {name: "Tomato C", orders_count: 100} | |
75 | + ] | |
76 | + assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_by: [:orders_count] | |
77 | + assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_by: {orders_count: {factor: 10}} | |
78 | + end | |
79 | + | |
80 | + def test_boost_where | |
81 | + store [ | |
82 | + {name: "Tomato A"}, | |
83 | + {name: "Tomato B", user_ids: [1, 2, 3]}, | |
84 | + {name: "Tomato C"}, | |
85 | + {name: "Tomato D"} | |
86 | + ] | |
87 | + assert_first "tomato", "Tomato B", boost_where: {user_ids: 2} | |
88 | + assert_first "tomato", "Tomato B", boost_where: {user_ids: {value: 2, factor: 10}} | |
89 | + end | |
90 | + | |
70 | 91 | end | ... | ... |