Search code examples
elasticsearchnestquerydsl

Filtering DSL Query Search - Elasticsearch


I was reading a few articles and documents over query context and filter context and learned that it is always best to use filter context if you do not need to do a full text search or scoring does not matter. In my case, I am wanting to return the logs that contain an ID... so I then realized I should just use a filter context instead of a query context. Besides the full text search or scoring is there a hard base line that defines when you should use one over the other?

So I went from my original DSL query search cmd:

GET /customer-simulation-es-app-logs*/_search
{
  "query": {
    "match": {
      "_id": "mJvG0nkBiU3wk_hrEd-8"
    }
  }

to the filter context:

GET /customer-simulation-es-app-logs*/_search
{
  
  "query": {
    "bool": {
      "filter": [
        {"match": {"_id": "mJvG0nkBiU3wk_hrEd-8"}}
      ]
    }
  }
}
}

Since, I am wanting to use NEST to perform the query search I took this approach.

    [HttpGet("GetAll/{_id}")]
    public async Task<EsSource> GetAll(String _id)
    {
        var response = await _elasticClient.SearchAsync<EsSource>(s => s
            .Index("customer-simulation-es-app-logs*")
            .Query(q => q
                 .Bool(b => b
                   .Filter(f => f
                      .Match(m => m.Field("_id").Query(_id))))));

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

Would this be the correct way to do a filter context using NEST?


Solution

  • That would be the correct way to issue a query with only a filter context. Some additional points that might help

    1. A term-level query on the _id field, like a term query should suffice, as there's no analysis chain involved
    2. If you know the index that contains the document, the get API would be a better option. Given a wildcard index pattern is being used though, implies that the index might not be known.
    3. NEST has convenient operator overloads on queries to make writing bool queries more succinct. The final query can be written more succinctly as
    var response = await _elasticClient.SearchAsync<EsSource>(s => s
        .Index("customer-simulation-es-app-logs*")
        .Query(q => +q
            .Match(m => m
                .Field("_id")
                .Query(_id)
            )
        )
    );