Get raw query from NEST client

ElasticsearchNest

Elasticsearch Problem Overview


Is it possible to get the raw search query from the NEST client?

var result = client.Search<SomeType>(s => s
                .AllIndices()
                .Type("SomeIndex")
                .Query(query => query
                    .Bool(boolQuery => BooleanQuery(searchRequest, mustMatchQueries)))
                );

I'd really like to debug why I am getting certain results.

Elasticsearch Solutions


Solution 1 - Elasticsearch

The methods to do this seem to change with each major version, hence the confusing number of answers. If you want this to work in NEST 6.x, AND you want to see the deserialized request BEFORE it's actually sent, it's fairly easy:

var json = elasticClient.RequestResponseSerializer.SerializeToString(request);

If you're debugging in Visual Studio, it's handy to put a breakpoint right after this line, and when you hit it, hover over the json variable above and hit the magnifying glass thingy. You'll get a nice formatted view of the JSON.

Solution 2 - Elasticsearch

You can get raw query json from RequestInformation:

var rawQuery = Encoding.UTF8.GetString(result.RequestInformation.Request);

Or enable trace on your ConnectionSettings object, so NEST will print every request to trace output

var connectionSettings = new ConnectionSettings(new Uri(elasticsearchUrl));
connectionSettings.EnableTrace(true);
var client = new ElasticClient(connectionSettings); 

NEST 7.x

Enable debug mode when creating settings for a client:

var settings = new ConnectionSettings(connectionPool)
    .DefaultIndex("index_name")
    .EnableDebugMode()
var client = new ElasticClient(settings); 

then your response.DebugInformation will contain information about request sent to elasticsearch and response from elasticsearch. Docs.

Solution 3 - Elasticsearch

For NEST / Elasticsearch.NET v6.0.2, use the ApiCall property of the IResponse object. You can write a handy extension method like this:

public static string ToJson(this IResponse response)
{
    return Encoding.UTF8.GetString(response.ApiCall.RequestBodyInBytes);
}

Or, if you want to log all requests made to Elastic, you can intercept responses with the connection object:

var node = new Uri("https://localhost:9200");
var pool = new SingleNodeConnectionPool(node);
var connectionSettings = new ConnectionSettings(pool, new HttpConnection());
connectionSettings.OnRequestCompleted(call =>
{
    Debug.Write(Encoding.UTF8.GetString(call.RequestBodyInBytes));
});

Solution 4 - Elasticsearch

In ElasticSearch 5.x, the RequestInformation.Request property does not exist in ISearchResponse<T>, but similar to the answer provided here you can generate the raw query JSON using the Elastic Client Serializer and a SearchDescriptor. For example, for the given NEST search query:

var results = elasticClient.Search<User>(s => s
    .Index("user")
    .Query(q => q                    
        .Exists(e => e
            .Field("location")
        )
    )            
);

You can get the raw query JSON as follows:

SearchDescriptor<User> debugQuery = new SearchDescriptor<User>()
    .Index("user")
    .Query(q => q                    
        .Exists(e => e
            .Field("location")
        )
    )
;

using (MemoryStream mStream = new MemoryStream())
{
    elasticClient.Serializer.Serialize(debugQuery, mStream);
    string rawQueryText = Encoding.ASCII.GetString(mStream.ToArray());
}

Solution 5 - Elasticsearch

Before making Request, from Nest Query - For Nest 5.3.0 :

var stream = new System.IO.MemoryStream();
elasticClient.Serializer.Serialize(query, stream );
var jsonQuery = System.Text.Encoding.UTF8.GetString(stream.ToArray());

Edit: It's changed from from Nest 6.x, and you can do below:

var json = elasticClient.RequestResponseSerializer.SerializeToString(request);

Solution 6 - Elasticsearch

on nest version 6 use

connextionString.DisableDirectStreaming();

then on response.DebugInformation you can see all information.

Solution 7 - Elasticsearch

Use result.ConnectionStatus.Request.

Solution 8 - Elasticsearch

While it's possible to get raw request/response through code, I find it much easier to analyze it with fiddler.
The reason is that I can easily analyze raw request, response, headers, Full URL, execution time - all together without any hassle of code changes.

Here's some reference links in case someone unfamiliar with fiddler wants to check details:
#1 https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/logging-with-fiddler.html
#2 https://stackoverflow.com/questions/24930987/nest-1-0-see-request-on-fiddler
#3 https://newbedev.com/how-to-get-nest-to-work-with-proxy-like-fiddler

Solution 9 - Elasticsearch

When using NEST 7 and you don't want to enable debug mode.

public static string GetQuery<T>(this IElasticClient client, SearchDescriptor<T> searchDescriptor) where T : class
    {
        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
        {
            client.RequestResponseSerializer.Serialize(searchDescriptor, ms);

            return Encoding.UTF8.GetString(ms.ToArray());
        }
    }

Solution 10 - Elasticsearch

How about using Fiddler ?! :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMark WalshView Question on Stackoverflow
Solution 1 - ElasticsearchTodd MenierView Answer on Stackoverflow
Solution 2 - ElasticsearchRobView Answer on Stackoverflow
Solution 3 - ElasticsearchPaul TaylorView Answer on Stackoverflow
Solution 4 - ElasticsearchHenry CView Answer on Stackoverflow
Solution 5 - ElasticsearchJay ShahView Answer on Stackoverflow
Solution 6 - ElasticsearchMahyarView Answer on Stackoverflow
Solution 7 - ElasticsearchrkrahlView Answer on Stackoverflow
Solution 8 - ElasticsearchJay ShahView Answer on Stackoverflow
Solution 9 - Elasticsearchacivic2nvView Answer on Stackoverflow
Solution 10 - ElasticsearchhavijView Answer on Stackoverflow