Commit 182c82e949c9f4c463ee19ecbcc6085d6890673c

Authored by Andrew Kane
1 parent efacf259

Added ability to boost fields

1 ## 0.7.8 [unreleased] 1 ## 0.7.8 [unreleased]
2 2
3 - Added `boost_by` and `boost_where` options 3 - Added `boost_by` and `boost_where` options
  4 +- Added ability to boost fields - `name^10`
4 - Added `select` option for `load: false` 5 - Added `select` option for `load: false`
5 6
6 ## 0.7.7 7 ## 0.7.7
@@ -118,6 +118,12 @@ limit: 20, offset: 40 @@ -118,6 +118,12 @@ limit: 20, offset: 40
118 118
119 ### Boosting 119 ### Boosting
120 120
  121 +Boost important fields
  122 +
  123 +```ruby
  124 +fields: ["title^10", "description"]
  125 +```
  126 +
121 Boost by the value of a field 127 Boost by the value of a field
122 128
123 ```ruby 129 ```ruby
@@ -192,6 +198,12 @@ Available options are: @@ -192,6 +198,12 @@ Available options are:
192 :text_end 198 :text_end
193 ``` 199 ```
194 200
  201 +To boost fields, use:
  202 +
  203 +```ruby
  204 +fields: [{"name^2" => :word_start}] # better interface on the way
  205 +```
  206 +
195 ### Language 207 ### Language
196 208
197 Searchkick defaults to English for stemming. To change this, use: 209 Searchkick defaults to English for stemming. To change this, use:
lib/searchkick/query.rb
@@ -15,6 +15,7 @@ module Searchkick @@ -15,6 +15,7 @@ module Searchkick
15 @term = term 15 @term = term
16 @options = options 16 @options = options
17 17
  18 + boost_fields = {}
18 fields = 19 fields =
19 if options[:fields] 20 if options[:fields]
20 if options[:autocomplete] 21 if options[:autocomplete]
@@ -22,7 +23,10 @@ module Searchkick @@ -22,7 +23,10 @@ module Searchkick
22 else 23 else
23 options[:fields].map do |value| 24 options[:fields].map do |value|
24 k, v = value.is_a?(Hash) ? value.to_a.first : [value, :word] 25 k, v = value.is_a?(Hash) ? value.to_a.first : [value, :word]
25 - "#{k}.#{v == :word ? "analyzed" : v}" 26 + k2, boost = k.split("^", 2)
  27 + field = "#{k2}.#{v == :word ? "analyzed" : v}"
  28 + boost_fields[field] = boost.to_i if boost
  29 + field
26 end 30 end
27 end 31 end
28 else 32 else
@@ -74,17 +78,19 @@ module Searchkick @@ -74,17 +78,19 @@ module Searchkick
74 else 78 else
75 queries = [] 79 queries = []
76 fields.each do |field| 80 fields.each do |field|
  81 + factor = boost_fields[field] || 1
77 shared_options = { 82 shared_options = {
78 fields: [field], 83 fields: [field],
79 query: term, 84 query: term,
80 use_dis_max: false, 85 use_dis_max: false,
81 - operator: operator 86 + operator: operator,
  87 + boost: factor
82 } 88 }
83 if field == "_all" or field.end_with?(".analyzed") 89 if field == "_all" or field.end_with?(".analyzed")
84 shared_options[:cutoff_frequency] = 0.001 unless operator == "and" 90 shared_options[:cutoff_frequency] = 0.001 unless operator == "and"
85 queries.concat [ 91 queries.concat [
86 - {multi_match: shared_options.merge(boost: 10, analyzer: "searchkick_search")},  
87 - {multi_match: shared_options.merge(boost: 10, analyzer: "searchkick_search2")} 92 + {multi_match: shared_options.merge(boost: 10 * factor, analyzer: "searchkick_search")},
  93 + {multi_match: shared_options.merge(boost: 10 * factor, analyzer: "searchkick_search2")}
88 ] 94 ]
89 if options[:misspellings] != false 95 if options[:misspellings] != false
90 distance = (options[:misspellings].is_a?(Hash) && options[:misspellings][:distance]) || 1 96 distance = (options[:misspellings].is_a?(Hash) && options[:misspellings][:distance]) || 1
test/boost_test.rb
@@ -67,6 +67,22 @@ class TestBoost < Minitest::Unit::TestCase @@ -67,6 +67,22 @@ class TestBoost < Minitest::Unit::TestCase
67 assert_first "tomato", "Tomato B", personalize: {user_ids: 2} 67 assert_first "tomato", "Tomato B", personalize: {user_ids: 2}
68 end 68 end
69 69
  70 + def test_boost_fields
  71 + store [
  72 + {name: "Red", color: "White"},
  73 + {name: "White", color: "Red Red Red"}
  74 + ]
  75 + assert_order "red", ["Red", "White"], fields: ["name^10", "color"]
  76 + end
  77 +
  78 + def test_boost_fields_word_start
  79 + store [
  80 + {name: "Red", color: "White"},
  81 + {name: "White", color: "Red Red Red"}
  82 + ]
  83 + assert_order "red", ["Red", "White"], fields: [{"name^10" => :word_start}, "color"]
  84 + end
  85 +
70 def test_boost_by 86 def test_boost_by
71 store [ 87 store [
72 {name: "Tomato A"}, 88 {name: "Tomato A"},