Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elasticsearch NEST filter by date range

I'm using Elastic search .Net NEST client that i never used before. What i'm trying to do is filter result by date range before scoring.

I'm using Object initializer syntax because it suits me best.

I have accomplished what i want with:

        var filter = new FilteredQuery();

        var queryForm = new TermQuery();
        queryForm.Field = "id";
        queryForm.Value = filterModel.Id;

        filter.Query &= queryForm;

        var rangeQuery = new DateRangeQuery();
        rangeQuery.Field = "datetime";
        rangeQuery.GreaterThanOrEqualTo = filterModel.DateBegin.Value.AddDays(-1);
        rangeQuery.LessThanOrEqualTo = filterModel.DateEnd.Value.AddDays(1);
        filter.Filter = rangeQuery;

        // Use boolean query
        searchRequest.Query = new BoolQuery() && filter;

This gives me request JSON like i expecting:

   {
  "from": 0,
  "size": 0,
  "query": {
    "filtered": {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "id": {
                  "value": "XXXX"
                }
              }
            }
          ]
        }
      },
      "filter": {
        "range": {
          "datetime": {
            "gte": "2015-12-31T00:00:00",
            "lte": "2016-05-05T00:00:00"
          }
        }
      }
    }
  }
}

But documentation about filtered query says "Deprecated in 2.0.0-beta1. Use the bool query instead with a must clause for the query and a filter clause for the filter".

Since this is the only way i found to include filter is there a better way to do this with NEST Object initializer syntax? How can i use "filter clause for the filter" or i must use range query and forget filter?

Thanks!

like image 590
boris Avatar asked May 04 '16 19:05

boris


1 Answers

There is a blog post explaining the changes in NEST 2.0 that came with ES 2.0.

In order to add your term and range filters to a bool/filter query using the Object Initializer syntax, you can do it with the new + special construct, which will cause the term query to be wrapped inside a bool query's filter clause:

    var queryForm = +new TermQuery();
    queryForm.Field = "id";
    queryForm.Value = filterModel.Id;

    var rangeQuery = +new DateRangeQuery();
    rangeQuery.Field = "datetime";
    rangeQuery.GreaterThanOrEqualTo = filterModel.DateBegin.Value.AddDays(-1);
    rangeQuery.LessThanOrEqualTo = filterModel.DateEnd.Value.AddDays(1);

    searchRequest.Query = queryForm && rangeQuery

See more details here

like image 176
Val Avatar answered Oct 17 '22 12:10

Val