Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you debug your Nest queries?

I'm new to Nest, and I very likely am not creating my query like I think I am. My question is more along the lines of teach a man to fish rather than give me a fish. However, I'll use my current problem as an example.

I have several documents in ElasticSearch of the type Series. I'll stub it out below without the attributes and public modifiers with just the information pertinent to the query:

class Series
{
    string Id {get; set;}
    DateTime StartDate {get; set;}
    DateTime EndDate {get; set;}
    HashSet<Role> ReleasableTo {get; set;}
}

These are all fine and dandy. I can Get() a Series object no problem. The problem I'm running into is trying to figure out how Nest is formatting my query. My immediate goal is to find the most recent Series that is releasable to Role.Visitor. I set up the Nest query like this:

ISearchResponse<Series> response = client
    .Search<Series>(r => 
         r.Filter(f => 
             f.Term<Role>(t=>t.ReleasableTo.First(), Role.Visitor))
    .SortDescending(ser => ser.EndDate).Size(1));

In my mind, this should be producing a query that filters the Series so it only considers the ones that are ReleasableTo my Role.Visitor, reverse sorts by end date, and limits the results to one returned. That would be exactly what I want. In the multiple thousands of records I have for Series, about 90% fit this profile. Unfortunately the query returns 0 results. There is no error, just no results. What I don't know is if I'm using the API incorrectly, if Nest is producing a query structure that doesn't make sense, or I simply don't know ElasticSearch well enough. When I remove the Filter clause I get a result, but I'm not guaranteed everyone is allowed to see it.

How do I view the JSON that Nest produces and sends to ElasticSearch?

like image 440
Berin Loritsch Avatar asked Jan 25 '15 17:01

Berin Loritsch


People also ask

How do you debug a query?

To debug a function, open the procedure calling that function and insert a breakpoint for the function you want to debug. Then, start debugging. Step through the code using the F11 key or Step Into, or press CTRL+F5 to move directly to the breakpoint. Press F11 or click Step Into to get inside the stored function.

How do you debug a database?

To debug a database object, follow these procedures in this order: Enable SQL Server debugging on your test project. Enable application debugging on the SQL Server instance that hosts the database you are testing. Set breakpoints in the Transact-SQL script of the database object(s) you are debugging.


2 Answers

You can get the values of search request URL and JSON request body as under:

var requestURL = response.RequestInformation.RequestUrl;
var jsonBody = Encoding.UTF8.GetString(response.RequestInformation.Request);

You can find other useful properties in RequestInformation for debugging.

like image 126
bittusarkar Avatar answered Sep 18 '22 11:09

bittusarkar


NEST is Baroque of .NET APIs. For 2.1+ on call level:

IElasticClient client = new ElasticClient();
var searchDescriptor = new SearchDescriptor<Series>();
var query = Query<Series>.Term(...);
var pretty = query.ToPrettyString(query);
var json = client.ToRawRequest(searchDescriptor.Query(descriptor => query));

On configuration level:

    var settings = new ConnectionSettings()
                     .PrettyJson().DisableDirectStreaming()
                     .OnRequestCompleted(details=> Debug.WriteLine(Encoding.UTF8.GetString(details.RequestBodyInBytes)));

On response level look into CallDetails.RequestBodyInBytes.

Used extensions:

    /// <summary>
    /// Converts search to raw JSON request for debugging.
    /// </summary>
    /// <typeparam name="T">The type.</typeparam>
    /// <param name="self">The self.</param>
    /// <param name="searchDescriptor">The search descriptor.</param>
    /// <returns>The string.</returns>
    public static string ToRawRequest<T>(this IElasticClient self, SearchDescriptor<T> searchDescriptor) where T : class
    {
        using (var output = new MemoryStream())
        {
            self.Serializer.Serialize(searchDescriptor, output);
            output.Position = 0;
            var rawQuery = new StreamReader(output).ReadToEnd();
            return rawQuery;
        }
    }

    /// <summary>
    /// Prints query into string.
    /// </summary>
    /// <param name="self">The self.</param>
    /// <returns>The value.</returns>
    public static string ToPrettyString(this QueryContainer self)
    {
        using (var settings = new ConnectionSettings())
        {
            var visitor = new DslPrettyPrintVisitor(settings);
            self.Accept(visitor);
            return visitor.PrettyPrint.Replace(Environment.NewLine, string.Empty);
        }                                                                         
    }
like image 26
Dzmitry Lahoda Avatar answered Sep 18 '22 11:09

Dzmitry Lahoda