Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nest MultiMatch Field Boost

I'm trying to boost some fields over others in a multiMatch search.

Looking at the docs I see you can create a Field with boost by doing this

var titleField = Infer.Field<Page>(p => p.Title, 2);

I haven't been able to figure out how that translates to Fields though.

Something like this isn't right

var bodyField = Infer.Field<Page>(p => p.Body);
var titleField = Infer.Field<Page>(p => p.Title, 2);
var metaDescriptionField = Infer.Field<Page>(p => p.MetaDescription, 1.5);
var metaKeywordsField = Infer.Field<Page>(p => p.Keywords, 2);

MultiMatchQuery multiMatchQuery = new MultiMatchQuery()
{
    Fields = Infer.Fields<Page>(bodyField, titleField, metaDescriptionField, metaKeywordsField),
            Query = search.Term
};

Do I need to use the string names for the fields like

var titleFieldString = "Title^2";

and pass those into Infer.Fields

like image 281
Andrew Walters Avatar asked Mar 12 '23 06:03

Andrew Walters


1 Answers

You can use the strongly typed Infer.Field<T>(); there is an implicit conversion from Field to Fields, and additional fields can be added with .And(). Here's an example

void Main()
{
    var client = new ElasticClient();

    Fields bodyField = Infer.Field<Page>(p => p.Body);
    var titleField = Infer.Field<Page>(p => p.Title, 2);
    var metaDescriptionField = Infer.Field<Page>(p => p.MetaDescription, 1.5);
    var metaKeywordsField = Infer.Field<Page>(p => p.Keywords, 2);

    var searchRequest = new SearchRequest<Page>()
    {
        Query = new MultiMatchQuery()
        {
            Fields = bodyField
                        .And(titleField)
                        .And(metaDescriptionField)
                        .And(metaKeywordsField),
            Query = "multi match search term"
        }
    };

    client.Search<Page>(searchRequest);
}

public class Page
{
    public string Body { get; set; }
    public string Title { get; set; }
    public string MetaDescription { get; set; }
    public string Keywords { get; set; }
}

this yields

{
  "query": {
    "multi_match": {
      "query": "multi match search term",
      "fields": [
        "body",
        "title^2",
        "metaDescription^1.5",
        "keywords^2"
      ]
    }
  }
}

You can also pass an array of Field which also implicitly converts to Fields

var searchRequest = new SearchRequest<Page>()
{
    Query = new MultiMatchQuery()
    {
        Fields = new[] {
            bodyField,
            titleField,
            metaDescriptionField,
            metaKeywordsField
        },
        Query = "multi match search term"
    }
};

As well as pass an array of strings

var searchRequest = new SearchRequest<Page>()
{
    Query = new MultiMatchQuery()
    {
        Fields = new[] {
            "body",
            "title^2",
            "metaDescription^1.5",
            "keywords^2"
        },
        Query = "multi match search term"
    }
};
like image 156
Russ Cam Avatar answered Mar 20 '23 14:03

Russ Cam