简体   繁体   English

MongoDB驱动程序C#查询优化

[英]MongoDb driver c# query optimization

I read in mongo db doc that I can use also LINQ but I don't understand some thing about it. 我在mongo db doc中读到,我也可以使用LINQ,但我对此一无所知。

For example, if I write: 例如,如果我写:

var result = collection.Find(filter);

and

var result = collection.AsQueryable()
              .Where(x => x.Foo == 114)

What is better? 什么是更好的?

LINQ filters on based of entire collection? LINQ筛选器基于整个集合吗? Before I get entire collection and then it filters? 在获得整个收藏之前,它会进行过滤吗? Or before filters and it give me the collection already filtered? 还是在过滤器之前,它给了我已经过滤的集合?

Both do pretty much the same. 两者几乎一样。

The LINQ API is a wrapper over the Collection API. LINQ API是Collection API的包装。

From briefly studying the sources of mongo-csharp-driver , I can see that the LINQ version calls either Collection.FindAs(...) or Collection.Distinct(...) . 通过简要研究mongo-csharp-driver的源代码,我可以看到LINQ版本调用了Collection.FindAs(...)Collection.Distinct(...) It constructs the IMongoQuery passed in the query parameter, based on the LINQ expression. 它基于LINQ表达式构造在query参数中传递的IMongoQuery For that, it uses the query builder API (the Query class), such as Query.EQ 为此,它使用查询构建器API( Query类),例如Query.EQ。

What is better? 什么是更好的?

It depends. 这取决于。

  • If you have types in C# code that represent structure of documents in the database, then you're likely to benefit from the LINQ API. 如果您使用C#代码中的类型表示数据库中文档的结构,则您可能会从LINQ API中受益。 You will benefit from strong typing, better readability, and you won't miss a renamed identifier whose name was passed as a string. 您将受益于强大的键入功能,更好的可读性,并且不会错过使用名称作为字符串传递的重命名标识符。
  • If you have dynamic structure of data, which has no concrete representation in code (you have some kind of metadata about a document, but not a class explicitly containing document properties). 如果您具有动态的数据结构,而代码中没有具体的表示形式(您具有某种有关文档的元数据,但没有明确包含文档属性的class )。 In such a case, using LINQ would be a struggle, and the raw Collection API would be a better choice. 在这种情况下,使用LINQ会很麻烦,原始的Collection API将是一个更好的选择。

LINQ filters on based of entire collection? LINQ筛选器基于整个集合吗? Before I get entire collection and then it filters? 在获得整个收藏之前,它会进行过滤吗? Or before filters and it give me the collection already filtered? 还是在过滤器之前,它给了我已经过滤的集合?

Since LINQ API implements IQueryable and not just IEnumeable , all enumerable methods (such as Where or OrderBy ) are not actually called, but rather are translated during compilation into code that builds expression trees. 由于LINQ API实现了IQueryable而不是IEnumeable ,因此实际上并未调用所有可枚举的方法(例如WhereOrderBy ),而是在编译过程中将其转换为生成表达式树的代码。 At runtime, the expression trees are built and passed to underlying query provider (implemented by MongoDB Driver in this case). 在运行时,将构建表达式树并将其传递给基础查询提供程序(在这种情况下,由MongoDB驱动程序实现)。 The query provider translates expression trees into regular MongoDB queries and executes them through the regular MongoDB API. 查询提供程序将表达式树转换为常规的MongoDB查询,并通过常规的MongoDB API执行它们。

See How to: Use Expression Trees to Build Dynamic Queries for more details. 有关更多详细信息,请参见如何:使用表达式树构建动态查询

So the query is actually executed in the database, and only the processed (filtered, ordered, or projected) results are returned to the application. 因此,查询实际上是在数据库中执行的,并且只有已处理(过滤,排序或计划)的结果返回给应用程序。

Yet, using LINQ API implies some performance overhead, because in addition to running the query, LINQ API also: 但是,使用LINQ API会带来一些性能开销,因为LINQ API除了运行查询之外,还:

  • builds expression trees to pass them to query provider 构建表达式树以将其传递给查询提供者
  • visits expression trees to translate them into native query 访问表达式树以将其转换为本地查询

In many cases this overhead is neglectable, but it depends on your requirements. 在许多情况下,这种开销可以忽略不计,但这取决于您的要求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM