I run a query to $.ajax({
url: 'json/local_json_file.json',
dataType: 'json', //or application/json
type: 'get',
cache:'false',
success: function(data) {
$(data).each(function(index,value) {
//some code
});
}
});
directly in Mongo (Robomongo, CLI, whatever) and it takes less than a second on several hundred thousand items:
select all items where field1=x, field2 =y, and field3=z
I then try to run the exact same thing from C# driver and it lags out(only "Aggregate filter" code is relevant, everything else is for context):
db.items.find( {
$and: [
{ CreatingOrgId: 1 },
{ LocationId: 941 },
{ StatusId: 1}
]
} )
What's my mistake here? Here are the queries as mongo sees them:
Edit: Looks like mapping the items to item object is what's killing my query to some degree. It's fairly fast (couple of seconds for a huge number of records) without the mapping, like so:
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;
Edit 2: Looks like automapper is a HUGE part of the problem here (taking the bson "item" object and converting it to a .NET view model). I am still interested in optimization of the .NET --> mongo query itself though (ignoring the automapper part), if anyone wants to answer.
答案 0 :(得分:3)
在C#中运行.ToListAsync()
时,将访问并返回查询的整个结果。
当您在命令行上运行.find()
时,只返回20(默认情况下)。
命令行上的一个更等效的测试是.find().toArray()
,它也将访问并返回所有结果。或者您可以在C#查询中设置限制。
如果您的完整结果集远大于shell批量大小,则可能会导致结果中的一些差异。如果未覆盖查询(即查询中的所有字段和返回的所有字段不在同一索引中),并且访问的数据不在内存中但是从磁盘访问,则差异会更大。
答案 1 :(得分:1)
假设您在3个字段上有索引,那么问题是mongo和C#查询之间的字段顺序不同。
C#查询是:LocationId,StatusId,CreatingOrgId
Mongo查询是:CreatingOrgId,LocationId,StatusId
您可以通过首先启用性能分析来验证MongoDB中的确切查询:
db.setProfilingLevel(2); // Profiles all queries.
然后,使用以下方法查找确切的查询:
db.system.profile.findOne();