Mongoose $maxDistance not precise
Since you are talking about geolocations, I'd suggest these changes:
- Use
2dsphere
index instead of2d
. This will ensure the search takes into consideration that the earth is not a 2d plane. - Change your model to represent the coordinates in the GeoJSON format.
So your schema should look something like this:
var LocationSchema = new mongoose.Schema({ name: String, location: { type: { type: String, default: "Point" }, coordinates: { type: [Number] } } }); LocationSchema.index({ location: '2dsphere' });
Now you can use Model.geoNear to perform your query. To get your distance in kilometers, you need to use the distanceMultiplier
option with the radius of earth in kilometers as the value. Don't forget the { spherical: true }
flag.
Note: I've used it as part of an aggregation and its pretty accurate. It should work the same in the above case also. Mongoose documentation doesn't talk about it. Use this from MongoDB docs
1 degree is aprox 111 kms at equator, where your 111.12 comes from. But as we move away from the equator it becomes less due to the convergence of the meridians(longitude) as we approach the pole.
Degree Lat Lng0° 110.574 km 111.320 km15° 110.649 km 107.551 km30° 110.852 km 96.486 km45° 111.132 km 78.847 km60° 111.412 km 55.800 km75° 111.618 km 28.902 km90° 111.694 km 0.000 km
You could use equirectangular approximation for this.
x = Δlat * cos (Δlng/2)y = ΔLngd = R ⋅ √x² + y²where Δlat & Δlng in radians & R = radius of earthΔlat is the difference between the 2 lats & Δlng that of lats