1
votes

I need to search for a term in only three fields in the document and sort the result according to where the searchTerm is found. So, for example, 3 documents are found: 1 with search term in field2, 2 with search term in field3, 3 with search term in field1.

I would like to see them in the order: 3, 1, 2.

I thought that I can do it using boosting. Now I use the following method:

var results = ES.Search<SearchData>(s => 
         s.TrackScores()
           .Query(q =>
                  q.Range(v => v.OnField(x => x.ExpirationDate).GreaterOrEquals(DateTime.Today)) &&
                  q.MultiMatch(m => 
                               m.OnFieldsWithBoost(b =>
                                                   b.Add(d => d.Field1, 3)
                                                    .Add(d => d.Field2, 2)
                                                    .Add(d => d.Field3, 1))
                                .Operator(Operator.And)
                                .Query(term)))
                    .Sort(doc => doc.OnField("_score").Descending())
                    .SortDescending(doc => doc.Date));

However, it appears that if I have a document with the 4 words equal to search term in field2 and another document with 1 word in field1, than the latter will have a smaller score.

Could someone please advise me what I should change in my query so that match in field1 had bigger score no matter how many matches are in field2 and field3 (and match in field 2 had bigger score than any number of matches in field3)?

One solution that I see is to set bigger values for field1 and field2 like that:

b.Add(d => d.Field1,1000)     
 .Add(d => d.Field2, 100)

but it's not ideal, so I really hope that you have a better one.

1
now I'm thinking towards custom scoring. Is there a way to calculate score only using boost scores (not including relevance, etc.)?Ekaterina
maybe I need something like this linkEkaterina

1 Answers

1
votes

My final solution is:

var results = ES.Search<SearchData>(
                s => s.TrackScores()
                    .Query(q => q.Range(v => v.OnField(x => x.ExpirationDate).GreaterOrEquals(DateTime.Today)) &&
                        (q.ConstantScore(cs => cs.Query(qcs => qcs.MultiMatch(m => m.OnFields(b => b.Field1).Operator(Operator.And).Query(searchTerm))).Boost(1000))
                        || q.ConstantScore(cs => cs.Query(qcs => qcs.MultiMatch(m => m.OnFields(b => b.Field2).Operator(Operator.And).Query(searchTerm))).Boost(10))
                        || q.ConstantScore(cs => cs.Query(qcs => qcs.MultiMatch(m => m.OnFields(b => b.Field3).Operator(Operator.And).Query(searchTerm))).Boost(1))))
                                        .Sort(doc => doc.OnField("_score").Descending())
                                        .SortDescending(doc => doc.Date));