Search code examples
elasticsearchfluentnest

Put SearchDescriptor into a separate variable and use it within a MultiSearch query


I'd like to separate my SearchDescriptor from my MultiSearch query to allow for easy reusability.

This is what I have now(before separation). It works perfect:

IMultiSearchResponse result = esClient
    .MultiSearch(search => search
        .Search<ElasticSearchCorporation>(a => a
            .Size(100)
            .Query(q => q
                .MultiMatch(query => query
                    .Type(TextQueryType.CrossFields)
                    .OnFieldsWithBoost(b => b
                        .Add(f => f.Summary, 1.6)
                        .Add(f => f.Summary.Suffix("ngram"), 1.5)
                        .Add(f => f.Description, 1.0))
                    .Query(searchQuery)))));

This is what I'm trying to do, but I've apparently done something wrong.

SearchDescriptor<ElasticSearchCompany> companySearchDescriptor = new SearchDescriptor<ElasticSearchCompany>();
companySearchDescriptor
    .Size(100)
    .Query(q => q
        .SimpleQueryString(query => query
            .OnFieldsWithBoost(b => b
                .Add(f => f.Summary, 1.6)
                .Add(f => f.Summary.Suffix("ngram"), 1.5)
                .Add(f => f.Description, 1.0)
                .Add(f => f.City.Suffix("ngram"), 1.1)
                .Add(f => f.City, 1.0))
            .Query(searchQuery)));

IMultiSearchResponse result = esClient
    .MultiSearch(search => search
        .Search(companySearchDescriptor));

I get this error: "The type arguments for method 'Nest.MultiSearchDescriptor.Search(System.Func,Nest.SearchDescriptor>)' cannot be inferred from the usage. Try specifying the type arguments explicitly."

However I did specify the type argument explicitly. That's what SearchDescriptor<ElasticSearchCompany> is for.

Edit 2: It's possible my misunderstanding has to do with the nuances of a fluent api.


Solution

  • .Search<>() takes a Func<SearchDescriptor<T>, SearchDescriptor<T>> not just a SearchDescriptor<T>.

    Try this:

    IMultiSearchResponse result = esClient
    .MultiSearch(search => search
        .Search<ElasticSearchCompany>(d => companySearchDescriptor));