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

VSO*_*VSO 3 mongodb mongodb-query mongodb-.net-driver

我直接在 Mongo 中运行查询select all items where field1=x, field2 =y, and field3=z(Robomongo、CLI,等等),对数十万个项目只需要不到一秒的时间:

db.items.find( { 
    $and: [ 
        { CreatingOrgId: 1 }, 
        { LocationId: 941 },
        { StatusId: 1}
    ] 
} )
Run Code Online (Sandbox Code Playgroud)

然后,我尝试从 C# 驱动程序运行完全相同的东西,但它滞后了(只有“聚合过滤器”代码相关,其他所有内容都用于上下文):

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;
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

编辑:看起来将项目映射到项目对象是在某种程度上杀死我的查询的原因。如果没有映射,它的速度相当快(大量记录只需几秒钟),如下所示:

    var rawItems = mongoItemsCollection
                             .Find(aggregateFilter)
                             .ToListAsync().Result;
Run Code Online (Sandbox Code Playgroud)

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

she*_*lak 5

当您.ToListAsync()在 C# 中运行时,将访问并返回查询的整个结果。

而当您.find()在命令行上运行时,仅返回 20(默认情况下)。

命令行上更等效的测试.find().toArray()也将访问并返回所有结果。或者您可以在 C# 查询中设置限制。

如果您的完整结果集比 shell 批量大小大很多,这可能会导致结果出现一些差异。如果查询没有被覆盖(即查询中的所有字段和返回的所有字段不在同一个索引中)并且访问的数据不在内存中而是从磁盘访问,这种差异会更严重。