Commit efacf2592151a25c3b820cb4d910bb14119af6f9

Authored by Andrew Kane
1 parent 23e4261f

Added boost_by and boost_where options

CHANGELOG.md
1 1 ## 0.7.8 [unreleased]
2 2  
  3 +- Added `boost_by` and `boost_where` options
3 4 - Added `select` option for `load: false`
4 5  
5 6 ## 0.7.7
... ...
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 &lt; 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
... ...