diff --git a/lib/chewy/query.rb b/lib/chewy/query.rb
index 28196b397..cc93d65a8 100644
--- a/lib/chewy/query.rb
+++ b/lib/chewy/query.rb
@@ -395,6 +395,28 @@ def boost_factor(factor, options = {})
chain { criteria.update_scores scoring }
end
+ # Add a weight scoring function to the search. All scores are
+ # added to the search request and combinded according to
+ # boost_mode and score_mode
+ #
+ # This probably only makes sense if you specify a filter
+ # for the weight as well.
+ #
+ # UsersIndex.weight(23, filter: { term: { foo: :bar} })
+ # # => {body:
+ # query: {
+ # function_score: {
+ # query: { ...},
+ # functions: [{
+ # weight: 23,
+ # filter: { term: { foo: :bar } }
+ # }]
+ # } } }
+ def weight(factor, options = {})
+ scoring = options.merge(weight: factor.to_i)
+ chain { criteria.update_scores scoring }
+ end
+
# Adds a random score to the search request. All scores are
# added to the search request and combinded according to
# boost_mode and score_mode
diff --git a/lib/chewy/search.rb b/lib/chewy/search.rb
index 46c3f1a39..45099d5fa 100644
--- a/lib/chewy/search.rb
+++ b/lib/chewy/search.rb
@@ -7,7 +7,7 @@ module Search
included do
singleton_class.delegate :explain, :query_mode, :filter_mode, :post_filter_mode,
:timeout, :limit, :offset, :highlight, :min_score, :rescore, :facets, :script_score,
- :boost_factor, :random_score, :field_value_factor, :decay, :aggregations,
+ :boost_factor, :weight, :random_score, :field_value_factor, :decay, :aggregations,
:suggest, :none, :strategy, :query, :filter, :post_filter, :boost_mode,
:score_mode, :order, :reorder, :only, :types, :delete_all, :find, :total,
:total_count, :total_entries, to: :all
diff --git a/spec/chewy/query_spec.rb b/spec/chewy/query_spec.rb
index b88c652b8..e97d36ac4 100644
--- a/spec/chewy/query_spec.rb
+++ b/spec/chewy/query_spec.rb
@@ -127,6 +127,14 @@
specify { expect(subject.boost_factor('23', filter: { foo: :bar}).criteria.scores).to eq([{ boost_factor: 23, filter: { foo: :bar } }]) }
end
+ describe '#weight' do
+ specify { expect(subject.weight('23')).to be_a described_class }
+ specify { expect(subject.weight('23')).not_to eq(subject) }
+ specify { expect(subject.weight('23').criteria.scores).to eq([ { weight: 23 } ]) }
+ specify { expect { subject.weight('23') }.not_to change { subject.criteria.scores } }
+ specify { expect(subject.weight('23', filter: { foo: :bar}).criteria.scores).to eq([{ weight: 23, filter: { foo: :bar } }]) }
+ end
+
describe '#random_score' do
specify { expect(subject.random_score('23')).to be_a described_class }
specify { expect(subject.random_score('23')).not_to eq(subject) }