Skip to content

Instantly share code, notes, and snippets.

@wbzyl
Forked from glyphobet/2dqueries.js
Created May 10, 2011 10:51
Show Gist options
  • Save wbzyl/964262 to your computer and use it in GitHub Desktop.
Save wbzyl/964262 to your computer and use it in GitHub Desktop.
Example showing that MongoDB uses native units for regular 2d queries, and radians for spherical 2d queries
> db.dropDatabase();
{ "dropped" : "test", "ok" : 1 }
>
> // These points are one degree apart, which (according to Google Maps) is about 110 km apart
> // at this point on the Earth.
> db.points.insert({location: [-122, 37]});
> db.points.insert({location: [-122, 38]});
> db.points.ensureIndex({location:"2d"});
>
>
> // Non-spherical geospatial queries use degrees:
>
> // $near finds both points because they are within 1 degree of this point between them
> db.points.find({location: {$near:[-122, 37.5], $maxDistance: 1}});
{ "_id" : ObjectId("4dc8fa2c01b6eeba7bb69856"), "location" : [ -122, 37 ] }
{ "_id" : ObjectId("4dc8fa2f01b6eeba7bb69857"), "location" : [ -122, 38 ] }
> // Same is true for $within $center
> db.points.find({location: {$within: {$center:[[-122, 37.5], 1]}}});
{ "_id" : ObjectId("4dc8fa2f01b6eeba7bb69857"), "location" : [ -122, 38 ] }
{ "_id" : ObjectId("4dc8fa2c01b6eeba7bb69856"), "location" : [ -122, 37 ] }
>
> // $near finds only one point because only the first point is within 1 degree of this point
> // If $near used radians, a distance of 1 radian would be 6,378 km, and this would return both points.
> db.points.find({location: {$near:[-122, 36.5], $maxDistance: 1}});
{ "_id" : ObjectId("4dc8fa2c01b6eeba7bb69856"), "location" : [ -122, 37 ] }
> // Same behavior for $within $center
> db.points.find({location: {$within: {$center:[[-122, 36.5], 1]}}});
{ "_id" : ObjectId("4dc8fa2c01b6eeba7bb69856"), "location" : [ -122, 37 ] }
>
>
> // Spherical geospatial queries use radians:
> var earthRadius = 6378; // in km
>
> // Finds both points because they are within 60 km of this point between them
> // If $nearSphere used degrees, this distance would be 0.009 degrees and wouldn't return any points
> db.points.find({location: {$nearSphere:[-122, 37.5], $maxDistance: 60/earthRadius}});
{ "_id" : ObjectId("4dc8fa2c01b6eeba7bb69856"), "location" : [ -122, 37 ] }
{ "_id" : ObjectId("4dc8fa2f01b6eeba7bb69857"), "location" : [ -122, 38 ] }
> // Same behavior for $within $centerSphere
> db.points.find({location: {$within: {$centerSphere:[[-122, 37.5], 60/earthRadius]}}});
{ "_id" : ObjectId("4dc8fa2f01b6eeba7bb69857"), "location" : [ -122, 38 ] }
{ "_id" : ObjectId("4dc8fa2c01b6eeba7bb69856"), "location" : [ -122, 37 ] }
>
> // Finds only one point because only the first point is within 60km of this point to the north
> db.points.find({location: {$nearSphere:[-122, 36.5], $maxDistance: 60/earthRadius}});
{ "_id" : ObjectId("4dc8fa2c01b6eeba7bb69856"), "location" : [ -122, 37 ] }
> // Same behavior for $within $centerSphere
> db.points.find({location: {$within: {$centerSphere:[[-122, 36.5], 60/earthRadius]}}});
{ "_id" : ObjectId("4dc8fa2c01b6eeba7bb69856"), "location" : [ -122, 37 ] }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment