From 182c82e949c9f4c463ee19ecbcc6085d6890673c Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Sun, 22 Jun 2014 16:35:40 -0700 Subject: [PATCH] Added ability to boost fields --- CHANGELOG.md | 1 + README.md | 12 ++++++++++++ lib/searchkick/query.rb | 14 ++++++++++---- test/boost_test.rb | 16 ++++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af9396c..7df1bc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.7.8 [unreleased] - Added `boost_by` and `boost_where` options +- Added ability to boost fields - `name^10` - Added `select` option for `load: false` ## 0.7.7 diff --git a/README.md b/README.md index fbc41fa..09b8f87 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,12 @@ limit: 20, offset: 40 ### Boosting +Boost important fields + +```ruby +fields: ["title^10", "description"] +``` + Boost by the value of a field ```ruby @@ -192,6 +198,12 @@ Available options are: :text_end ``` +To boost fields, use: + +```ruby +fields: [{"name^2" => :word_start}] # better interface on the way +``` + ### Language Searchkick defaults to English for stemming. To change this, use: diff --git a/lib/searchkick/query.rb b/lib/searchkick/query.rb index f2fcc11..da92dc7 100644 --- a/lib/searchkick/query.rb +++ b/lib/searchkick/query.rb @@ -15,6 +15,7 @@ module Searchkick @term = term @options = options + boost_fields = {} fields = if options[:fields] if options[:autocomplete] @@ -22,7 +23,10 @@ module Searchkick else options[:fields].map do |value| k, v = value.is_a?(Hash) ? value.to_a.first : [value, :word] - "#{k}.#{v == :word ? "analyzed" : v}" + k2, boost = k.split("^", 2) + field = "#{k2}.#{v == :word ? "analyzed" : v}" + boost_fields[field] = boost.to_i if boost + field end end else @@ -74,17 +78,19 @@ module Searchkick else queries = [] fields.each do |field| + factor = boost_fields[field] || 1 shared_options = { fields: [field], query: term, use_dis_max: false, - operator: operator + operator: operator, + boost: factor } if field == "_all" or field.end_with?(".analyzed") shared_options[:cutoff_frequency] = 0.001 unless operator == "and" queries.concat [ - {multi_match: shared_options.merge(boost: 10, analyzer: "searchkick_search")}, - {multi_match: shared_options.merge(boost: 10, analyzer: "searchkick_search2")} + {multi_match: shared_options.merge(boost: 10 * factor, analyzer: "searchkick_search")}, + {multi_match: shared_options.merge(boost: 10 * factor, analyzer: "searchkick_search2")} ] if options[:misspellings] != false distance = (options[:misspellings].is_a?(Hash) && options[:misspellings][:distance]) || 1 diff --git a/test/boost_test.rb b/test/boost_test.rb index 1eafaa5..9cb64d6 100644 --- a/test/boost_test.rb +++ b/test/boost_test.rb @@ -67,6 +67,22 @@ class TestBoost < Minitest::Unit::TestCase assert_first "tomato", "Tomato B", personalize: {user_ids: 2} end + def test_boost_fields + store [ + {name: "Red", color: "White"}, + {name: "White", color: "Red Red Red"} + ] + assert_order "red", ["Red", "White"], fields: ["name^10", "color"] + end + + def test_boost_fields_word_start + store [ + {name: "Red", color: "White"}, + {name: "White", color: "Red Red Red"} + ] + assert_order "red", ["Red", "White"], fields: [{"name^10" => :word_start}, "color"] + end + def test_boost_by store [ {name: "Tomato A"}, -- libgit2 0.21.0