To write your own custom score boost function just override GetQuery method in ElasticSearchRequestBuilder like this:
public class ElasticSearchRequestBuilder2 : ElasticSearchRequestBuilder
{
public ElasticSearchRequestBuilder2(IElasticSearchFiltersBuilder searchFiltersBuilder, IElasticSearchAggregationsBuilder searchAggregationsBuilder, ISettingsManager settingsManager) : base(searchFiltersBuilder, searchAggregationsBuilder, settingsManager)
{
}
protected override Query GetQuery(VirtoCommerceSearchRequest request)
{
var baseQuery = base.GetQuery(request);
if (request.Take == 0)
{
return baseQuery;
}
return new FunctionScoreQuery()
{
Query = baseQuery,
BoostMode = FunctionBoostMode.Replace,
ScoreMode = FunctionScoreMode.Sum,
Functions = new List<FunctionScore>
{
new ScriptScoreFunction
{
Script = new Script(new InlineScript()
{
Source = "doc['ranktuning'].size()!=0 ? doc['ranktuning'].value * _score : _score"
})
}
}
};
}
}
And then register the new search builder class in Module Initialize :
serviceCollection.AddSingleton<IElasticSearchRequestBuilder, ElasticSearchRequestBuilder2>();
In this example the function multiplies original document score by the special int “ranktuning“ dynamic property value:
To access document field value in the function code use: doc['fieldname'].value
To check if field is in the document (an error will be thrown if not): doc['fieldname'].size()!=0
The function declaration will be translated into a ES query similar to:
{
"query": {
"function_score": {
"boost_mode": "replace",
"functions": [
{
"script_score": {
"script": {
"source": "doc[\u0027ranktuning\u0027].size()!=0 ? doc[\u0027ranktuning\u0027].value * _score : _score"
}
}
}
],
"query": {
"multi_match": {
"analyzer": "standard",
"fields": [
"__content"
],
"operator": "and",
"query": "test"
}
},
"score_mode": "sum"
}
},
"size": 20
}
We can see that the function code is passed into function_score
query and the original query is wrapped within it.