Search code examples
c#elasticsearchnest

Converting DSL Query to NEST (elasticsearch)


My DSL query that I have in Kibana is :

GET elastic-search-app-log*/_search
{
  "_source": ["@timestamp", "level", "messageTemplate", "message"],  
  "query": {
    "match": {
      "_id" : "x5pcgHkBlRaz9flxW1uw"
    }
  }
}

Which will return the following in the CLI:

{
  "took" : 19,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "elastic-search-app-logs-development-2021-05",
        "_type" : "_doc",
        "_id" : "x5pcgHkBlRaz9flxW1uw",
        "_score" : 1.0,
        "_source" : {
          "@timestamp" : "2021-05-18T11:43:25.6155311-05:00",
          "level" : "Error",
          "message" : "Something bad happened",
          "messageTemplate" : "Something bad happened"
        }
      }
    ]
  }
}

This is what I attempted to do, but it gives me an error when I build it:

        [HttpGet("{_id}")]
        public async Task<EsSource> Get(String _id) 
        {
            var response = await _elasticClient.Search<EsSource>(s => s
                .Source(src => src.Includes(i => i
                                  .Fields(f => f.TimeStamp,
                                          f => f.Level,
                                          f => f.MessageTemplate,
                                          f => f.Message)))
                .Index("elastic-search-app-logs*")
                .Query(q => q
                    .Match(m => m.Field("_id").Query(_id))));

            return response?.Documents?.FirstOrDefault();
        }

My EsSource Model class:

public class EsSource
{
    public String TimeStamp { get; set; }
    public String Level { get; set; }
    public String MessageTemplate { get; set; }
    public String Message { get; set; }
}

Error in VS19 says:

ESController.cs(39,28,47,61): error CS1061: 'ISearchResponse<EsSource>' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'ISearchResponse<EsSource>' could be found (are you missing a using directive or an assembly reference?)

Am I not translating the DSL query to NEST correctly? I am extremely new to this and would love all the help I can get.


Solution

  • You need to change Search method to SearchAsync as return type from Search is ISearchResponse<EsSource> and it doesn't contain GetAwaiter so you can't await on it.

    [HttpGet("{_id}")]
    public async Task<EsSource> Get(String _id) 
    {
        var response = await _elasticClient.SearchAsync<EsSource>(s => s
            .Source(src => src.Includes(i => i
                              .Fields(f => f.TimeStamp,
                                      f => f.Level,
                                      f => f.MessageTemplate,
                                      f => f.Message)))
            .Index("elastic-search-app-logs*")
            .Query(q => q
                .Match(m => m.Field("_id").Query(_id))));
    
        return response?.Documents?.FirstOrDefault();
    }