Search code examples
c#asp.net-corenest

How to write DSL Highlight to NEST queries Highlight?


I want to write this DSL query into NEST c# query like below

public async Task<IEnumerable<T>> GetEsDataWithMultiMatch<T>(string indexName, string[] fieldName, string fieldValue) where T : class

        var designHighliterString = fieldName != null ? string.Join(',', fieldName.Select(x => x + ": {}")) : string.Empty;

            var searchResponse = await _elasticClient.SearchAsync<T>(s => s
                                      .Size(10000)
                                      .Index(indexName)
                                      .Highlight(h=>h.Fields(designHighliterString)) //Build issue
                                      .Query(q => (q
                                      .MultiMatch(m => m
                                      .Fields(fieldName)
                                      .Query(fieldValue)
                                      .Type(TextQueryType.PhrasePrefix)
                                       )))).ConfigureAwait(false);

            var documents = searchResponse.Documents;
            return documents;
        }

which throwing build issue, so what is the exact syntax can write in generic methods ?


Solution

  • You cannot pass string to property Fields.

    Syntax for it is as below

    .Fields(
            fs => fs
                .Field(p => p.Name),          
            fs => fs
                .Field(p => p.LeadDeveloper)
                .PreTags("<name>")
                .PostTags("</name>")
            )    
    

    Edit 1 Below is not a full implementation . But it will give you some idea how to construct query for generic

    1. Constraint "T" to a generic interface

    public static ISearchResponse<T> MySearch<T>(IElasticClient client)
        where T : class, ISearchDTO =>
        client.Search<T>(s => s
            .From(0)
            .Size(10)
            .Index("")
            .Query(q => q
                 .MultiMatch(m => m
                 .Fields(f => f.Field(p => p.firstName).Field(p => p.lastName))
                 .Query("abc")
                 .Type(TextQueryType.PhrasePrefix)
                ) -- same for highlight
            )
        );
    
        public interface ISearchDTO
        {
            string firstName { get; }
            string lastName { get; }
        }
    
    whatever model you will pass must implement ISearchDTO
    

    2. Construct required parts and pass it to search method

    
    // Construct highlight query
    private static IHighlight CreateHighLightFields()
            {
                var fieldDescriptor = new Func<HighlightFieldDescriptor<SearchDto>, IHighlightField>[2];
    
                fieldDescriptor[0] = hf => hf.Field("name");
                fieldDescriptor[1] = hf => hf.Field("shortName");
    
                IHighlight highlight = new HighlightDescriptor<SearchDto>()
                                       .Fields(fieldDescriptor);
    
                return highlight;
            }
    
    // Generic search method
    public static ISearchResponse<T> Search<T>(this IElasticClient client, Fields fields, string indexName, IHighlight highlight)
            where T : class => client.Search<T>(s => s
                                     .From(0)
                                     .Size(10)
                                     .Index(indexName)
                                     .Highlight(h => highlight) //Build issue
                                     .Query(q => q
                                         .MultiMatch(m => m
                                             .Fields(fields)
                                             .Query("abc")
                                             .Type(TextQueryType.PhrasePrefix)
                                         )
                                     )
                               );
    ##usage
    
    Fields fields = ((Fields)Infer.Field<SearchDto>(f => f.Name))
                                                   .And<SearchDto>(f => f.ShortName1);
    
    var response = _client.Search<SearchDto>(fields, "abc", CreateHighLightFields());