Search code examples
elasticsearchnest

Elastic search querying without Nest


I got tired of trying to figure out how to query my data the way i wanted using Nest - it always seems to infer the wrong url to post the search request to?

Anyway - I have put together this ugly looking code that seems to work:

using (var client = new HttpClient())
            {
                client.BaseAddress = node;
                var content = new StringContent("{\"size\": 0,\"query\": {\"bool\": {\"must\": [{\"wildcard\": {\"FlogDetail.AdditionalInfo.QueryString-filter[slug]\": \"*" + slug +  "*\"}},{\"range\": {\"@timestamp\": {\"gte\": \"now-1d/d\",\"lt\": \"now\"}}}]}},\"aggs\": {\"results\": {\"date_histogram\": {\"field\": \"@timestamp\",\"interval\": \"hour\"}}}}", Encoding.UTF8, "application/json");
                var result = await client.PostAsync(@"usage*/_search", content);
                string resultContent = await result.Content.ReadAsStringAsync();

                JObject o = JObject.Parse(resultContent);

                return o;
            }

Now, before I go and make it more sane and pretty, is there any issue with querying ES like this?

My mian issue using Nest was that I couldn't see a way to query the wildcard index that you can see I am able to do with plain old C#

If anyone knows the answer to that last bit I'd be grateful!


Solution

  • There's nothing wrong with querying Elasticsearch in the way that you've proposed. NEST supports querying against wildcards, single indices, multiple indices e.g.

    var searchResponse = client.Search<MyDocument>(s => s
        .Index("usage*")
        .AllTypes()
        .Query(q => q
            .MatchAll()
        )
    );
    

    sends the following request

    POST http://localhost:9200/usage*/_search
    {
      "query": {
        "match_all": {}
      }
    }
    

    NEST's convention is to map a POCO to a type within an index, and you can set up a convention for a given POCO with DefaultMappingFor<T>(...) on ConnectionSettings

    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    
    var settings = new ConnectionSettings(pool)
        .DefaultMappingFor<MyDocument>(m => m
            .IndexName("usage*")
        );
    
    var client = new ElasticClient(settings);
    
    var searchResponse = client.Search<MyDocument>(s => s
        .AllTypes()
        .Query(q => q
            .MatchAll()
        )
    );
    

    There is no convention for specifying that the type name should be omitted for a given POCO however, so the call to .AllTypes() is still needed in the search request to search across all types in indices matching usage*.