ucef
ucef

Reputation: 557

catch query sent to elasticSearch

I want to catch the query sent to elastic, i am using nest 7.6.1. How can i see the query of the request. Here is the code :

ISearchResponse<Document> initialResponse = this.clientBundle.GetClient().Search<Document>
                (
                    scr => scr
                     .From(0)
                     .Take(scrollSize)
                     .Query(q =>
                                q.Bool(y => boolQuery)
                            )
                     .Scroll(scrollTimeout));

Upvotes: 0

Views: 625

Answers (1)

Russ Cam
Russ Cam

Reputation: 125518

By default, NEST serializes directly to the request stream and deserializes from the response stream, but this can be disabled globally or on a per-request basis such that these are buffered in memory and are available in the API call details on the response

var client = new ElasticClient(settings);

var searchResponse = client.Search<object>(s => s
    .RequestConfiguration(r => r
        .DisableDirectStreaming()
    )
);

var requestJson = Encoding.UTF8.GetString(searchResponse.ApiCall.RequestBodyInBytes);

If you're wanting to see all requests and responses, you may want to set DisableDirectStreaming(...) on ConnectionSettings and configure a delegate on using OnRequestCompleted(...) to print these out

var defaultIndex = "default_index";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));

var settings = new ConnectionSettings(pool)
    .DefaultIndex(defaultIndex)
    .PrettyJson()
    .OnRequestCompleted(callDetails =>
    {
        if (callDetails.RequestBodyInBytes != null)
        {
            Console.WriteLine(
                $"{callDetails.HttpMethod} {callDetails.Uri} \n" +
                $"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
        }
        else
        {
            Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
        }

        Console.WriteLine();

        if (callDetails.ResponseBodyInBytes != null)
        {
            Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                     $"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
                     $"{new string('-', 30)}\n");
        }
        else
        {
            Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                     $"{new string('-', 30)}\n");
        }
    });

var client = new ElasticClient(settings);

var searchResponse = client.Search<object>();

This is essentially what .EnableDebugMode() on ConnectionSettings does.


If you want to be able to see requests without making an actual request, you can serialize the request with the RequestResponseSerializer

var client = new ElasticClient(settings);

ISearchRequest searchRequest = new SearchDescriptor<object>()
    .Query(q => q
        .Match(m => m
            .Field("foo")
            .Query("bar")
        )
    );

var json = client.RequestResponseSerializer.SerializeToString(searchRequest);

With this approach, the request should be cast to the request interface to serialize properly e.g. SearchDescriptor<T> -> ISearchRequest.

An alternative approach is to use InMemoryConnection

var defaultIndex = "default_index";
var settings = new ConnectionSettings(new InMemoryConnection())
    .DefaultIndex(defaultIndex)
    .DisableDirectStreaming();

var client = new ElasticClient(settings);

var response = client.Search<object>(s => s
    .Query(q => q
        .Match(m => m
            .Field("foo")
            .Query("bar")
        )
    )
);

var json = Encoding.UTF8.GetString(response.ApiCall.RequestBodyInBytes);

As before, OnRequestCompleted(...) can be used with this approach to capture all requests.

Upvotes: 1

Related Questions