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 查询本身的优化感兴趣(忽略自动映射器部分)。
当您.ToListAsync()在 C# 中运行时,将访问并返回查询的整个结果。
而当您.find()在命令行上运行时,仅返回 20(默认情况下)。
命令行上更等效的测试.find().toArray()也将访问并返回所有结果。或者您可以在 C# 查询中设置限制。
如果您的完整结果集比 shell 批量大小大很多,这可能会导致结果出现一些差异。如果查询没有被覆盖(即查询中的所有字段和返回的所有字段不在同一个索引中)并且访问的数据不在内存中而是从磁盘访问,这种差异会更严重。