MongoDB驱动程序C#查询优化

时间:2019-06-10 10:04:03

标签: c# mongodb performance linq

我在mongo db文档中读到,我也可以使用LINQ,但是我对此一无所知。

例如,如果我写:

var result = collection.Find(filter);

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

有什么更好的?

基于整个集合的LINQ筛选器? 在获得整个收藏之前,它会进行过滤吗?还是在过滤器之前,它给了我已经过滤的集合?

1 个答案:

答案 0 :(得分:4)

两者都差不多。

LINQ API是Collection API的包装。

通过简要研究mongo-csharp-driver的来源,我可以看到LINQ版本调用了Collection.FindAs(...)Collection.Distinct(...)。它基于LINQ表达式构造在IMongoQuery参数中传递的query。为此,它使用查询构建器API(Query类),例如Query.EQ

  

有什么更好的?

要视情况而定。

  • 如果您有C#代码类型表示数据库中文档的结构,则您可能会从LINQ API中受益。您将受益于强大的键入功能,更好的可读性,并且不会错过使用名称作为字符串传递的重命名标识符。
  • 如果您具有动态的数据结构,该结构在代码中没有具体表示(您具有某种有关文档的元数据,但没有明确包含文档属性的class)。在这种情况下,使用LINQ会很麻烦,原始的Collection API将是一个更好的选择。
  

基于整个集合的LINQ筛选器?在获得整个收藏之前,它会进行过滤吗?还是在过滤器之前,它给了我已经过滤的集合?

由于LINQ API实现了IQueryable而不是仅实现IEnumeable,因此实际上并未调用所有可枚举的方法(例如WhereOrderBy),而是在编译期间进行了翻译到构建表达式树的代码中。在运行时,将构建表达式树并将其传递给基础查询提供程序(在这种情况下,由MongoDB驱动程序实现)。查询提供程序将表达式树转换为常规的MongoDB查询,并通过常规的MongoDB API执行它们。

有关更多详细信息,请参见How to: Use Expression Trees to Build Dynamic Queries

因此,查询实际上是在数据库中执行的,并且只有已处理(过滤,排序或计划)的结果返回给应用程序。

但是,使用LINQ API意味着一些性能开销,因为LINQ API除了运行查询之外,还:

  • 构建表达式树以将其传递给查询提供者
  • 访问表达式树以将其转换为本地查询

在许多情况下,这种开销可以忽略不计,但这取决于您的要求。