Commit 182c82e949c9f4c463ee19ecbcc6085d6890673c
1 parent
efacf259
Exists in
master
and in
21 other branches
Added ability to boost fields
Showing
4 changed files
with
39 additions
and
4 deletions
Show diff stats
CHANGELOG.md
README.md
... | ... | @@ -118,6 +118,12 @@ limit: 20, offset: 40 |
118 | 118 | |
119 | 119 | ### Boosting |
120 | 120 | |
121 | +Boost important fields | |
122 | + | |
123 | +```ruby | |
124 | +fields: ["title^10", "description"] | |
125 | +``` | |
126 | + | |
121 | 127 | Boost by the value of a field |
122 | 128 | |
123 | 129 | ```ruby |
... | ... | @@ -192,6 +198,12 @@ Available options are: |
192 | 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 | 207 | ### Language |
196 | 208 | |
197 | 209 | Searchkick defaults to English for stemming. To change this, use: | ... | ... |
lib/searchkick/query.rb
... | ... | @@ -15,6 +15,7 @@ module Searchkick |
15 | 15 | @term = term |
16 | 16 | @options = options |
17 | 17 | |
18 | + boost_fields = {} | |
18 | 19 | fields = |
19 | 20 | if options[:fields] |
20 | 21 | if options[:autocomplete] |
... | ... | @@ -22,7 +23,10 @@ module Searchkick |
22 | 23 | else |
23 | 24 | options[:fields].map do |value| |
24 | 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 | 30 | end |
27 | 31 | end |
28 | 32 | else |
... | ... | @@ -74,17 +78,19 @@ module Searchkick |
74 | 78 | else |
75 | 79 | queries = [] |
76 | 80 | fields.each do |field| |
81 | + factor = boost_fields[field] || 1 | |
77 | 82 | shared_options = { |
78 | 83 | fields: [field], |
79 | 84 | query: term, |
80 | 85 | use_dis_max: false, |
81 | - operator: operator | |
86 | + operator: operator, | |
87 | + boost: factor | |
82 | 88 | } |
83 | 89 | if field == "_all" or field.end_with?(".analyzed") |
84 | 90 | shared_options[:cutoff_frequency] = 0.001 unless operator == "and" |
85 | 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 | 95 | if options[:misspellings] != false |
90 | 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 | 67 | assert_first "tomato", "Tomato B", personalize: {user_ids: 2} |
68 | 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 | 86 | def test_boost_by |
71 | 87 | store [ |
72 | 88 | {name: "Tomato A"}, | ... | ... |