NEST V5 How to use FunctionScoreQuery/FunctionScoreFunction to always boost a particular field


#1

Hi All,

I am really new to Elastic Search so please bear with me. I can see lots of examples in the Elasticsearch Reference guide for using the Elasticsearch.NET low level client but not many examples on how to use the NEST high level client for FunctionScoreQuery/FunctionScoreFunction.

I am using NEST to build up a SearchRequest which will utilize a custom FunctionScoreQuery. I've set the Query property and am now trying to set the Functions property to a valid list of FunctionScoreFunctions. For simplicity, let's assume I have a simple Product object which has two properties, one a List called 'BoughtBefore' (which is a list of customer Ids) and one a float called 'Boost' which is the result of a custom boost calculation I have based on some of the properties in the Product object.

Firstly, I am trying to create a FunctionScoreFunction which would always apply a boost of 2 to the score if a customer has bought this product before.

This is the code I have for this FunctionScoreFunction:

var boughtBeforeBoostScore = new FunctionScoreFunction()
{
    Filter = new BoolQuery()
    {
        Must = new List<QueryContainer>() { new TermQuery() { Field = "boughtBefore", Value = customerId, Boost = 2.0 } }
    }
};

I have tried lots of things to no avail and at run time i get the exception: 'Can not write function score json for FunctionScoreFunction'.

Similarly, with the Product.Boost field, I am trying to create another FunctionScoreFunction which uses my Product.Boost field to replace the boost value calculated by Elasticsearch. Here is the code for this FunctionScoreFunction below:

var calculatedBoostScore = new FunctionScoreFunction()
{
    Filter = new FunctionScoreQuery() { Functions = new List<IScoreFunction> { new FieldValueFactorFunction() { Field = "boost" } }, BoostMode = FunctionBoostMode.Replace }
};

If someone could provide some guidance with these functions and how to properly implement them using NEST, that would be much appreciated.

Thanks


(Russ Cam) #2

Hey @davey1990, did you see the NEST example usage for function_score query? It demonstrates both the fluent API and object initializer syntax, both producing the example json shown.


#3

Hi @forloop, thank you so much for the link to that doc, I completely missed it in the documentation. I think I was mainly looking through the Elasticsearch.NET doco (not NEST) instead.


(Russ Cam) #4

No worries! If you have any further questions, feel free to ask them here :thumbsup:


#5

Hi @forloop, I have another question :smiley:

I have got the FucntionScoreQuery working with the FieldValueFactorFunction on the 'boost' field on its own but I can't seem to combine it together with boosting on the 'boughtBefore' field if it matches the current customer Id performing the search.

I have this function for the 'boost' field:

        var calculatedBoostScore = new FieldValueFactorFunction()
        {
            Field = "boost",
            Factor = 1
        };

and this function for the 'boughtBefore' field but I don't think this is the correct way to do it?

        var boughtBefore = new FieldValueFactorFunction()
        {
            Field = "boughtBefore",
            Filter = new TermQuery() { Field = "boughtBefore", Boost = 3.5, Value = customerId }
        };

These two functions are then assigned to the one FunctionScoreQuery:

        var functionScoreQuery = new FunctionScoreQuery
        {
            Query = alreadyfilteredQuery,
            Functions = GetFunctionScoreFunctions(searchRequest.CustomerId)
        };

Should I actually have two separate FunctionScoreQueries?

Thanks for your help


(Russ Cam) #6

You can have multiple functions within one function_score query and control how the scores computed for each function are combined together with score_mode, and then how they are combined with the score from the query using boost_mode.

Your query looks OK to me, assuming GetFunctionScoreFunctions() returns an IEnumerable<IScoreFunction>. You can get additional detail for how scores are calculated for each document with explain on the search request.


#7

Thanks @forloop!

I've got it all working now! I also had to set a weight for my function score functions which I didn't have and it's now boosting the results as desired.


(system) #8

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.