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
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 |
README.md
@@ -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"}, |