Combine `should` with `filter` search API

I wanted to translate my DSL query search that will return the results I am looking for, but when I translated my DSL query to NEST when I hit the end point it just shows [].

Documentation that I read:

Bool query usage

Writing bool queries

My DSL query search that actually returns values:

GET /customer-simulation-es-app-logs*/_search
{
  "_source": ["@timestamp", "level", "message", "messageTemplate"], 
 "query": {
    "bool": {
      "should": [
        { "match": {"level" : "Error"} },
        { "match": {"level" : "Information"} }
      ], 
      "filter": [
        {
          "range": {
            "@timestamp": {
               "gte": "2021-07-14T00:00:00.000-05:00",
               "lt": "2021-07-14T23:59:59.999-05:00"
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

What I get when I run the DSL query:

enter image description here

My attempt to translate it to NEST:

EsSource.cs:

        public class EsSource
        {
            [Date(Name = "@timestamp")]
            public DateTimeOffset timestamp { get; set; }
            public String level { get; set; }
            public String messageTemplate { get; set; }
            public String message { get; set; }
            //       public List<EsExceptions> exceptions { get; set; }
            //       public EsFields fields { get; set; }
        }


[HttpGet("GetMonthlyLogs")]
public async Task<List<EsSource>> GetLogsByDate()
{
    var response = await _elasticClient.SearchAsync<EsSource>(s => s
          .Size(3000) // must see about this
          .Source(src => src.Includes(i => i
                            .Fields(f => f.timestamp,
                                    f => f.level,
                                    f => f.messageTemplate,
                                    f => f.message)))
          .Index("customer-simulation-es-app-logs*")
          .Query(q => q
              .Bool(b => b
                  .Should(
                        m => m
                        .Match(ma => ma
                            .Field(fa => fa.level.Contains("Error"))),
                        m => m
                        .Match(ma => ma
                            .Field(fa => fa.level.Contains("Information"))))
                  .Filter(f => f.DateRange(dr => dr
                  .Field("@timestamp")
                      .GreaterThanOrEquals("2021-07-14T00:00:00.000-05:00")
                      .LessThanOrEquals(DateTime.Now)))
                  .MinimumShouldMatch(1))));


    return response?.Documents.ToList();
}

I even attempted to change the .field() inside of the should to see if that would help but it does not

.Query(q => q
                      .Bool(b => b
                          .Should(
                                m => m
                                .Match(ma => ma
                                    .Field(fa => fa.level)
                                    .Name("Error")),
                                m => m
                                .Match(ma => ma
                                    .Field(fa => fa.level)
                                    .Name("Information")))

Even this above returns an empty array.

enter image description here

Am I not translating the DSL query to NEST correctly?

Hi there! It looks like you're very close to the correct syntax for what you're trying to achieve. In this case, you need to specify the text you wish to search for in the level field.

To do this, using the fluent syntax, you specify it by providing a Query value.

var response = await Client.SearchAsync<EsSource>(s => s
    .Size(3000) // must see about this
    .Source(src => src.Includes(i => i
        .Fields(f => f.timestamp,
            f => f.level,
            f => f.messageTemplate,
            f => f.message)))
    .Index("customer-simulation-es-app-logs*")
    .Query(q => q
        .Bool(b => b
            .Should(
                m => m.Match(ma => ma.Field(fa => fa.level).Query("Error")),
                m => m.Match(ma => ma.Field(fa => fa.level).Query("Information")))
            .Filter(f => f.DateRange(dr => dr
                .Field("@timestamp")
                .GreaterThanOrEquals("2021-07-14T00:00:00.000-05:00")
                .LessThanOrEquals(DateTime.Now)))
            .MinimumShouldMatch(1))));

The above should translate the to query you showed, matching documents where the level is "Error" OR "Information".

Does this answer your question?

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.