MongoDb的C#驱动程序查询优化

4
我可以在MongoDB文档中看到,我也可以使用LINQ,但是我不理解其中的一些内容。
例如,如果我写下以下代码:
var result = collection.Find(filter);

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

什么更好?
根据整个集合进行LINQ过滤? 在获取整个集合之前进行过滤?还是在过滤之前就已经给我过滤后的集合了?

1
https://ericlippert.com/2012/12/17/performance-rant/ - mjwills
LINQ 应该转换为 Mongo 查询。 - ProgrammingLlama
Linq对于C#开发人员来说更易读,但与MongoDB的find命令相比,它会带来一些性能问题。我更喜欢使用Find()命令来获得更好的性能。 - Ravi
MongoDB驱动程序将LINQ转换为聚合管道。对于像您提到的查询,我建议您使用第一种方法。有时对于非常简单的查询,例如Count(),这两者之间的差异会很大。 collection.Count(new BsonDocument())比collection.AsQueryable().Count()快得多。 - Mohammad Taherian
1个回答

6

两者基本上做的都是相同的事情。

LINQ API是Collection API的包装器。

从简要研究mongo-csharp-driver的源代码来看,我可以看到LINQ版本调用Collection.FindAs(...)Collection.Distinct(...)。它根据LINQ表达式构建传递给query参数的IMongoQuery。为此,它使用查询构建器API(Query类),例如Query.EQ

哪个更好?

这取决于具体情况。

如果您在C#代码中有代表数据库文档结构的类型,则很可能会从LINQ API中受益。您将从强类型、更好的可读性中受益,并且不会错过已传递为字符串名称的重命名标识符。
如果您具有动态数据结构,其在代码中没有具体表示(您拥有有关文档的某些元数据,但不是显式包含文档属性的类),则在这种情况下使用LINQ将是一种挑战,原始集合API将是更好的选择。
由于LINQ API实现了IQueryable而不仅仅是IEnumeable,因此所有可枚举方法(例如Where或OrderBy)实际上并未被调用,而是在编译期间被转换为构建表达式树的代码。在运行时,构建表达式树并将其传递给底层查询提供程序(在此情况下由MongoDB Driver实现)。查询提供程序将表达式树转换为常规的MongoDB查询,并通过常规的MongoDB API执行它们。

请参阅如何:使用表达式树构建动态查询以获取更多详细信息。

因此,查询实际上是在数据库中执行的,只返回已处理(过滤、排序或投影)的结果到应用程序。

然而,使用LINQ API意味着存在一些性能开销,因为除了运行查询外,LINQ API还:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接