Reputation: 4702
I have a collection with 200,000+ documents in that I'm filtering with a few where clauses.
Here's my query in Mongoose:
const assets = await GpsLog
.where('gps_time')
.gte(first)
.lte(last)
.where('location')
.within()
.geometry(geoFence);
Where geofence
is a GeoJSON polygon.
The shell query I'm running is:
db.gps_log.find({
'gps_time': {
$gte: first,
$lte: last
},
'location': {
'$geoIntersects': {
'$geometry': {
'type': 'Polygon',
'coordinates': // polygon
}
}
}
})
The Mongoose query completes in anywhere between 5 to 11 seconds, whereas the shell query completes in 0.5s.
I translated the shell query to execute in Mongoose as:
const res = await GpsLog.find({
'gps_time': {
$gte: 1539648000,
$lte: 1539820800
},
'location': {
'$geoIntersects': {
'$geometry': geoFence
}
}
}).lean().exec();
But it's still taking 4+ seconds to execute.
Am I missing something with the speed difference?
Upvotes: 3
Views: 1011
Reputation: 203359
The Mongo shell, when you perform a query, returns a cursor and reads (at most) 20 results from it. After that, you need to exhaust the cursor (read all results) through one of various methods.
So what you're basically testing is how long it takes in the Mongo shell to return a cursor and read 20 results from it. In your case, that takes 0.5s.
However, Mongoose, by default, reads all results. So if you want to do a fair comparison between Mongoose and the shell, you should read all the results in the shell as well, for instance by using the toArray
method on the cursor:
db.gps_log.find({ ... }).toArray()
Alternatively, you can ask Mongoose to return a cursor instead of reading all results immediately:
const cursor = GpsLog.find({ ... }).lean().cursor();
cursor.on('data', doc => { ... }).on('close', () => { ... });
Upvotes: 2