Q:

Search the fields of tickets with date range

I have the following model
public class Ticket
{
    public string Id { get; set; }

    public string Question { get; set; }

    public DateTime CreateDate { get; set; }

    public DateTime ClosedDate { get; set; }

    public int Votes { get; set; }
}

I'm using ElasticSearch Nest client to search for tickets where any field contains a certain text within a date range. 
I tried the following:
        var result = client. Search<Ticket>(
            s => s.Query(q => 
                            q.Bool(b => 
                                b.Must(ms => ms. QueryString(qs => qs. Query(term)))
                                 .Filter(f => 
                                         f.Bool(bb => 
                                                bb. Must(ms => ms. DateRange(dr => dr. GreaterThanOrEquals(from).LessThanOrEquals(to))
            ))))));

It returns all tickets regardless of the time specified. 
It also only search for complete word while I want to search for any part of the word in the text. 
Any ideas? 

A:

The DateRange query requires a Field value for the field in Elasticsearch to run against.  When a value is not provided for this, NEST considers the query to be conditionless and does not serialize it as part of the query sent. 
For example, given
var term = "term";
var to = DateTime. Now;
var from = to. AddDays(-7);

your current query serializes to
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "term"
          }
        }
      ]
    }
  }
}

If the Field is added
var result = client. Search<Ticket>(s => s
    .Query(q => q
        .Bool(b => b
            .Must(ms => ms
                .QueryString(qs => qs
                    .Query(term)
                )
            )
            .Filter(f => f
                .Bool(bb => bb
                    .Must(ms => ms
                        .DateRange(dr => dr
                            .Field(df => df. CreateDate)
                            .GreaterThanOrEquals(from)
                            .LessThanOrEquals(to)
                        )
                    )
                )
            )
        )
    )
);

this now serializes to
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "term"
          }
        }
      ],
      "filter": [
        {
          "bool": {
            "must": [
              {
                "range": {
                  "createDate": {
                    "gte": "2018-07-17T12:20:02.8659934+10:00",
                    "lte": "2018-07-24T12:20:02.8659934+10:00"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Using operator overloading on queries, this can be written more succinctly
var result = client. Search<Ticket>(s => s
    .Query(q => q
        .QueryString(qs => qs
                .Query(term)
        ) && +q
        .DateRange(dr => dr
            .Field(df => df. CreateDate)
            .GreaterThanOrEquals(from)
            .LessThanOrEquals(to)
        )
    )
);

which serializes to 
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "term"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "createDate": {
              "gte": "2018-07-17T12:21:50.2175114+10:00",
              "lte": "2018-07-24T12:21:50.2175114+10:00"
            }
          }
        }
      ]
    }
  }
}

