I am using Elastic Search in C# using the NEST strongly typed client. I have an index containing Entries:
[ElasticType(Name = "Entry", IdProperty = "Id")]
public class Entry
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Award { get; set; }
public int Year { get; set; }
}
Where Year is the year of the entry, eg 2012, and Award is the type of Award the Entry won, which can be null.
I then want to search these Entries using boosting for different properties. In the following code, I want results to be ranked higher that match on the Title, than those that match on the Description.
private IQueryResponse<Entry> GetMatchedEntries(string searchText)
{
return _elasticClient.Search<Entry>(
body =>
body.Query(q =>
q.QueryString(qs =>
qs.OnFieldsWithBoost(d =>
d.Add(entry => entry.Title, 5.0)
.Add(entry => entry.Description, 2.0))
.Query(searchText))));
}
I have now been asked to Boost the results by those which have won Awards, and also Boost newer Entries (ie by the Year).
How do I do this? Is it something that needs to be done as part of the indexing service, or as part of the search?
Returns documents matching a positive query while reducing the relevance score of documents that also match a negative query. You can use the boosting query to demote certain documents without excluding them from the search results.
NEST is an official high-level client created by Elasticsearch that maps all requests and responses as types and provides an interface to execute queries. Let's add the NEST Client from NuGet via package manager or by running the following command from the directory where the .csproj file lives: dotnet add package NEST.
The score represents how relevant a given document is for a specific query. The default scoring algorithm used by Elasticsearch is BM25.
You can achieve this through a combination of a boosting
query and custom_score
query
instead of boosting year we alter the score based on the year because:
(_score + 2013) > (_score + 1999)
Newer results will float to the top.
By using a boosting query we can effectively demote results that are missing the award field.
see: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-boosting-query.html https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html
_client.Search<Entry>(s=>s
.Query(q =>q
.Boosting(bq=>bq
.Positive(pq=>pq
.CustomScore(cbf=>cbf
.Query(cbfq=>cbfq
.QueryString(qs => qs
.OnFieldsWithBoost(d =>
d.Add(entry => entry.Title, 5.0)
.Add(entry => entry.Description, 2.0)
)
.Query(searchText)
)
)
.Script("_score + doc['year'].value")
)
)
.Negative(nq=>nq
.Filtered(nfq=>nfq
.Query(qq=>qq.MatchAll())
.Filter(f=>f.Missing(p=>p.Award))
)
)
.NegativeBoost(0.2)
)
)
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With