【问题标题】:Is there an "Explain Query" for MongoDB Linq?MongoDB Linq 是否有“解释查询”?
【发布时间】:2012-10-26 15:03:26
【问题描述】:

有没有办法在 Linq 查询上运行 .explain() 或等效项?我想知道

  • 实际 JSON 查询的文本
  • .explain() 的输出(使用的索引等)
  • 如果有查询的执行时间也很好

【问题讨论】:

    标签: c# linq mongodb query-optimization mongodb-.net-driver


    【解决方案1】:

    如果你有一个查询包装器,你可以很容易地获得 Json;

    var qLinq = Query<T>.Where(x => x.name=="jim");
    Console.WriteLine(qLinq.ToJson());
    

    MongoCursor 上还有一个 Explain() 方法,所以你可以这样做;

    var exp = Collection.FindAs<T>(qLinq).Explain()
    Console.WriteLine(exp.ToJson());
    

    所以如果你想花时间,“millis”就在那里;

    var msTaken = exp.First(x => x.Name == "millis").Value.AsInt32;
    

    如果你有IQueryable,试试这样的;

    void Do(MongoCollection col, IQueryable iq)
    {
            // Json Mongo Query
            var imq = (iq as MongoQueryable<Blob>).GetMongoQuery();
            Console.WriteLine(imq.ToString());
    
            // you could also just do;
            // var cursor = col.FindAs(typeof(Blob), imq);
            var cursor = MongoCursor.Create(typeof(Blob), col, imq, ReadPreference.Nearest);
            var explainDoc = cursor.Explain();
    
            Console.WriteLine(explainDoc);
        }//Do()
    

    【讨论】:

    • 谢谢。我们的大部分查询来自IQueryable 对象。也许更好的问题是如何将IQueryable 变成IMongoQuery
    • 朝着那个方向前进并不容易,但你可以做到 - 请参阅更新的答案。另一种方法是在 Mongo Linq 层上放置一个存储库,以便您可以直接使用 Query 对象,进行日志记录然后返回 IQueryable 而不是尝试将 IQueryable 转换为 Query
    • 感谢您的帮助。您的解决方案实际上并没有编译。查看我的更新,了解对我实际有用的内容(注意我必须深入了解Expression 以获得where 子句)。
    • 对不起,我瞎写了。无论如何,我认为这比这容易得多。表达式可能是一个红鲱鱼,我们真的想要一个 MongoCursor,见上文。
    • 最新版本的Driver有一个IQueryable的“Explain”扩展方法。
    【解决方案2】:

    如果您希望在库中使用此功能,我刚刚创建了一个名为

    的 GitHub 项目

    .NET 的 MongoDB 查询助手

    https://github.com/mikeckennedy/mongodb-query-helper-for-dotnet

    它会:

    • 将 LINQ 查询解释为强类型对象(例如是否使用索引)
    • 将 LINQ 查询转换为在 MongoDB 中运行的 JavaScript 代码

    如果您觉得有趣,请查看并贡献。

    【讨论】:

      【解决方案3】:

      是的,有。它显示了.explain 所做的所有事情,并且有一个用于详细说明的布尔值(包括执行时间):

      var database = new MongoClient().GetServer().GetDatabase("db");
      var collection = database.GetCollection<Hamster>("Hamsters");
      
      var explanation = collection.AsQueryable().Where(hamster => hamster.Name == "bar").Explain(true);
      Console.WriteLine(explanation);
      

      但它不显示查询。这是一个扩展方法:

      public static string GetMongoQuery<TItem>(this IQueryable<TItem> query)
      {
          var mongoQuery = query as MongoQueryable<TItem>;
          return mongoQuery == null ? null : mongoQuery.GetMongoQuery().ToString();
      }
      

      用法:

      var query = collection.AsQueryable().Where(hamster => hamster.Name == "bar").GetMongoQuery();
      Console.WriteLine(query);
      

      【讨论】:

        【解决方案4】:

        在 mongodb 3 C# 中,我使用了以下内容:

        var users = Mongo.db.GetCollection<User>("Users");
        var r = users(m => m._id == yourIdHere)
            .Project(m => new { m._id, m.UserName, m.FirstName, m.LastName })
            .Limit(1);
        
        Console.WriteLine(r.ToString());
        

        结果:

        find({ "_id" : ObjectId("56030e87ca42192008ed0955") }, { "_id" : 1, "UserName" : 1, "FirstName" : 1, "LastName" : 1 }).limit(1) 
        

        【讨论】:

        • 这不是r.ToString()吗?我对上面的代码如何产生你指定的结果感到困惑。
        • 你是对的。我更正了代码示例。它应该是 r.ToString() 而不是 users.ToString()
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-03-11
        • 1970-01-01
        • 1970-01-01
        • 2012-07-23
        • 2010-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多