3

The answers MongoDB - can't use .explain() to get query info in C# code? or Is there an "Explain Query" for MongoDB Linq? are outdated and the classes and methods doesn't exist anymore in recent versions of the C# driver.

Kdog
  • 286
  • 3
  • 13
  • I am also trying to look for equivalent of Explain() and hint and not able to find anything on this in C#. Any update on this? – shanti Jun 07 '19 at 06:28
  • @shanti yeah I was able to get past it eventually! Check out my answer below. If you need to test the performance of queries with joins(lookups) the procedure is a little bit more involved. – Kdog Jun 11 '19 at 15:54

1 Answers1

2

As a workaround I was able to use the find syntax with options overload to run explain on the queries I wanted to tune.

    [Fact]
    public async Task Metrics()
    {
        var options = new FindOptions
        {
            Modifiers = new BsonDocument("$explain", true)
        };
        var queryable = await MongoDb.Collection.Find("{ Paid: false}", options).As<StatsBsonDocument>().ToListAsync(); // StatsBsonDocument BsonDocument  
        //Console.WriteLine(queryable.First());
        queryable.First().GetStats();            
    }



public class StatsBsonDocument
{
    public dynamic queryPlanner { get; set; }
    public ExecutionStats executionStats { get; set; }
    public dynamic serverInfo { get; set; }

    public void GetStats()
    {
        try
        {
            Console.WriteLine($"{queryPlanner.winningPlan.inputStage.stage}");
        }
        catch (Exception e)
        {
            Console.WriteLine($"executionSuccess {executionStats.executionSuccess}, stage {queryPlanner.winningPlan.stage},");
        }
        Console.WriteLine($"{executionStats.nReturned} returned documents, {executionStats.executionTimeMillis}ms execution");
        Console.WriteLine($"{executionStats.totalKeysExamined} keys examined , {executionStats.totalDocsExamined} documents examined");
        Console.WriteLine($"index vs returned {(decimal)executionStats.totalKeysExamined / executionStats.nReturned}, " +
        $"scanned documents/returned {(decimal)executionStats.totalDocsExamined / executionStats.nReturned}");
        Console.WriteLine();

        // AND_SORTED stage or an AND_HASH stage. index intersection
    }
}

public class QueryPlanner
{
    public dynamic plannerVersion;
    public string Namespace;
    public dynamic indexFilterSet;
    public dynamic parsedQuery;
    public dynamic winningPlan;
    public dynamic rejectedPlans;
}

public class ExecutionStats
{
    public bool executionSuccess;
    public int nReturned;
    public int executionTimeMillis;
    public int totalKeysExamined;
    public int totalDocsExamined;
    public dynamic executionStages;
    public dynamic allPlansExecution;
}
Kdog
  • 286
  • 3
  • 13
  • Thanks @Kdog , I will try adding $explain in FindOptions and update here... – shanti Jun 13 '19 at 06:05
  • If I simply add Modifiers in FindOptions, it works. But since my indexes are case insensitive and are using collation, I am using this query = collection.Find(filter, options: new FindOptions { Collation = request.SearchCollation, Modifiers = new BsonDocument("$explain", true) }).SortByDescending(x => x._Id).Limit(request.Limit); var explain = query.Project(new BsonDocument()).FirstOrDefault()?.ToJson(); It is giving an exception that OP_QUERY does not support collations. – shanti Jun 27 '19 at 09:49