I read the docs and its not very clear what the difference is between the two.
The only difference I found is that in nearSphere it explicitly says that Mongo calculates distances for $nearSphere using spherical geometry. But this is achievable using $near as well is it not?
The keyword is sphere
to differentiate between $near and $nearSphere.
As you are aware, $nearSphere
is stated to calculate distance using spherical geometry. This is related to the Earth map projection (distortion). Where MongoDB 2d indexes is based on Cartesian and MongoDB 2dsphere indexes is based on Geodesic.
Enough theory, let's use some examples. Let's say we have two documents as below:
db.map.insert({ "_id": "Westfield London", "location": [ -0.22157, 51.507176 ] });
db.map.insert({ "_id": "Green Lanes Shopping Centre", "location": [ -0.098092, 51.576198 ] });
The manual for both operators specify that we can use:
2dsphere
index for location data defined as GeoJSON points2d
index for location data defined as legacy coordinate pairs
Index: 2dsphere , Query: GeoJSON
db.map.createIndex({"location": "2dsphere"});
db.map.find({"location":{"$nearSphere":{"$geometry":{"type":"Point", "coordinates":[ -0.127748, 51.507333 ] }}}});
db.map.find({"location":{"$near":{"$geometry":{"type":"Point", "coordinates":[ -0.127748, 51.507333 ]}}}});
In this case, both queries will return the same result, because the index is stored in 2dsphere
.
Result:
[ /* $nearSphere */
{"_id" : "Westfield London"},
{"_id" : "Green Lanes Shopping Centre"}
]
[ /* $near */
{"_id" : "Westfield London"},
{"_id" : "Green Lanes Shopping Centre"}
]
Index: 2d , Query: Legacy Coordinates
db.map.createIndex({"location": "2d"});
db.map.find({"location":{"$nearSphere":[ -0.127748, 51.507333 ]}});
db.map.find({"location":{"$near":[ -0.127748, 51.507333 ]}});
This is where the distinction happens, the result for $nearSphere
is calculated spherically despite the index, while $near
is calculated in flat projection.
Result:
[ /* $nearSphere */
{"_id" : "Westfield London"},
{"_id" : "Green Lanes Shopping Centre"}
]
[ /* $near */
{"_id" : "Green Lanes Shopping Centre"},
{"_id" : "Westfield London"}
]
See gist: JS test script of the above example. This was tested using MongoDB v3.4.4.
Also see Geospatial Indexes and Queries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With