Database Reference
In-Depth Information
So to query efficiently on both location and services, you'd create the following com-
pound index:
> db.locations.ensureIndex({loc: '2d', services: 1})
This makes finding all retail stores with a nursery pretty trivial:
> db.locations.find({loc: [-73.977842, 40.752315], services: 'nursery'})
There's not much more to compound spatial indexes than that. If you're ever in
doubt about whether they're effective for your application, be sure to try running
explain() on the relevant queries.
E.4
Spherical geometry
All of the spatial queries I've described thus far use a flat-earth model for distance
computations. In particular, the database uses Euclidean distance to determine the
distance between points. 4 For a lot of use cases, including finding the closest n loca-
tions to a given point, this is perfectly acceptable, and the simplicity of the math
ensures the fastest query result.
But the reality is that the earth is roughly spherical. 5 This means that the Euclidean
distance calculations become less and less accurate as the distance between points
increases. For this reason, MongoDB also supports distance calculations based on a
two-dimensional spherical model. These queries yield more accurate distance results
at only a slight performance cost.
To use spherical geometry, you need only make sure that all coordinates are stored
in longitude-latitude order and that any distances are expressed in radians. You can
then deploy most of the queries expressed earlier in their spherical forms. For exam-
ple, $nearSphere is the spherical equivalent of $near and is expressed as follows:
> db.zips.find({'loc': {$nearSphere: [ -73.977842, 40.752315 ]}}).limit(3)
The geoNear command also supports spherical calculations with the addition of the
{ spherical: true } option:
> db.runCommand({'geoNear': 'zips',
near: [-73.977842, 40.752315], num: 2, spherical: true})
Finally, you can use $centerSphere to query within a circle using spherical distances.
Just be sure that when specifying the radius, you use radians:
center = [-73.977842, 40.752315]
radius_in_degrees = 0.11
radius_in_radians = radius_in_degrees * (Math.PI / 180);
db.zips.find({loc: {$within:
{$centerSphere: [center, radius_in_radians ] }}})
4
http://en.wikipedia.org/wiki/Euclidean_distance
5
Roughly speaking because it's technically an oblate spheroid, which means that it bulges at the equator.
 
Search WWH ::




Custom Search