为什么我的 .NET MongoDb 驱动程序查询非常慢?

Why is my .NET MongoDb Driver Query Horribly Slow?

我 运行 直接在 Mongo(Robomongo、CLI 等)中对 select all items where field1=x, field2 =y, and field3=z 进行查询,并且在几十万个项目上花费的时间不到一秒钟:

db.items.find( { 
    $and: [ 
        { CreatingOrgId: 1 }, 
        { LocationId: 941 },
        { StatusId: 1}
    ] 
} )

然后我尝试 运行 来自 C# 驱动程序的完全相同的东西,但它滞后了(只有 "Aggregate filter" 代码是相关的,其他一切都是为了上下文):

FilterDefinition<BsonDocument> locationsFilter;  = Builders<BsonDocument>.Filter.Eq("LocationId", 941);
FilterDefinition<BsonDocument> orgFilter = Builders<BsonDocument>.Filter.Eq("CreatingOrgId", 1);
FilterDefinition<BsonDocument> statusFilter = Builders<BsonDocument>.Filter.Eq("StatusId", 1);

FilterDefinition<BsonDocument> aggregateFilter = locationsFilter & statusFilter & orgFilter;

        List<ItemViewModel> stuffList = mongoItemsCollection
                                             .Find(aggregateFilter)
                                             .Project(x => Mapper.Map<BsonDocument, StuffViewModel>(x))
                                             .ToListAsync().Result;

我这里有什么错误?以下是 mongo 看到的查询:

编辑:看起来将项目映射到项目对象在某种程度上阻碍了我的查询。它在没有映射的情况下相当快(大量记录只需几秒钟),如下所示:

    var rawItems = mongoItemsCollection
                             .Find(aggregateFilter)
                             .ToListAsync().Result;

编辑 2:看起来 automapper 是这里问题的重要组成部分(获取 bson "item" 对象并将其转换为 .NET 视图模型)。我仍然对 .NET 的优化感兴趣 --> mongo 查询本身(忽略自动映射器部分),如果有人想回答的话。

假设您有 3 个字段的索引,那么问题是 mongo 和 C# 查询之间的字段顺序不同。

C# 查询是:LocationId、StatusId、CreatingOrgId

Mongo 查询是:CreatingOrgId、LocationId、StatusId

您可以通过首先启用分析来验证 MongoDB 中的确切查询:

db.setProfilingLevel(2); // Profiles all queries.

然后,使用以下方法找到确切的查询:

db.system.profile.findOne();

当您在 C# 中 运行 .ToListAsync() 时,将访问和 return 编辑查询的全部结果。

而当您在命令行上 运行 .find() 时,只有 20(默认)被 returned。

命令行上更等效的测试是 .find().toArray(),它也将访问和 return 所有结果。或者您可以在 C# 查询中设置一个限制。

如果您的完整结果集比 shell 批次大小大很多,这可能是您的结果存在差异的部分原因。如果查询未被覆盖(即查询中的所有字段和 returned 的所有字段不在同一索引中)并且如果访问的数据不在内存中但访问从磁盘。