我有一个包含200,000多个文档的集合,其中我在过滤几个where子句。
这是我在猫鼬中的查询:
#include <Windows.h>
LARGE_INTEGER begin, end, frequency;
double timeElapsed = 0.0;
QueryPerformanceFrequency(&frequency);
for (int i = 0; i < 100; i++) {
QueryPerformanceCounter(&begin);
myFunctionToTest();
QueryPerformanceCounter(&end);
// get microsecs
timeElapsed = ((end.QuadPart - begin.QuadPart) * 1000.0 / frequency.QuadPart) * 1000;
std::cout << timeElapsed << std::endl;
appendToCsvFile(timeElapsed);
}
const assets = await GpsLog
.where('gps_time')
.gte(first)
.lte(last)
.where('location')
.within()
.geometry(geoFence);
是一个GeoJSON多边形。
我正在运行的shell查询是:
geofence
Mongoose查询完成时间为5到11秒,而shell查询完成时间为0.5s。
我翻译了要在Mongoose中执行的shell查询:
db.gps_log.find({
'gps_time': {
$gte: first,
$lte: last
},
'location': {
'$geoIntersects': {
'$geometry': {
'type': 'Polygon',
'coordinates': // polygon
}
}
}
})
但是执行仍然需要4秒钟以上的时间。
我错过了速度差的东西吗?
答案 0 :(得分:2)
执行查询时,Mongo Shell将返回一个游标并从中读取(最多)20个结果。之后,您需要通过多种方法之一来耗尽光标(读取所有结果)。
因此,您基本上要测试的是Mongo shell返回一个游标并从中读取20个结果要花费多长时间。就您而言,这需要0.5秒。
但是,猫鼬默认情况下会读取所有结果。因此,如果您想在Mongoose和Shell之间进行公平的比较,则还应读取Shell中的所有结果,例如,通过使用光标上的toArray
方法:
db.gps_log.find({ ... }).toArray()
或者,您可以要求Mongoose return a cursor,而不是立即读取所有结果:
const cursor = GpsLog.find({ ... }).lean().cursor();
cursor.on('data', doc => { ... }).on('close', () => { ... });