Home > Software design >  How to write DSL Highlight to NEST queries Highlight?
How to write DSL Highlight to NEST queries Highlight?

Time:08-05

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 ?

CodePudding user response:

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());
  • Related