Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between $center and $centerSphere in Mongo?

Currently, we are using $centerSphere to find nearby cities. One example is that for the locality Bee Cave in Texas, USA, $centerSphere correctly found the only city Austin in a radius of 30 kilometers (As per documentation, it was converted in radians). Now, for the city Lautoka in Fiji (Lat: -17.6169618, Long: 177.4504609) it is giving the error "Spherical distance would require (unimplemented) wrapping". This is question one: what does this error mean?

We tried implementing the same by using $center. I'm aware we need to give distance in miles rather than radians. After implementing, for Bee Cave, I got US cities that were thousands or hundreds of miles away. One example is Albuquerque. I'm unable to understand why these cities are coming even after following Mongo documentation properly.

I'm using the query (for Bee Cave, TX)

db.places.find{
   "geo": {
      $geoWithin: { $center: [ [ -97.9524, 30.3061 ] , 18.64 ] }
   }
}
like image 481
Mithil Bhoras Avatar asked Sep 07 '25 02:09

Mithil Bhoras


1 Answers

$centerSphere can't handle large distances, especially if it has to wrap around the poles, see this JIRA ticket.

Regarding $geoWithin it does not accept the distance in miles, but rather the circle’s radius as measured in the units used by the coordinate system, so latitude and longitude as per the documentation. That results in a very large bounding box that does include Albuquerque

bounding box

You use $near instead that allows to specify a radius in meters. For example if you use this as your test data:

db.places.insert( {
   name: "Bee Cave, Texas",
   location: { type: "Point", coordinates: [ -97.9524, 30.3061 ]  }
} );
db.places.insert( {
   name: "Austin, Texas",
   location: { type: "Point", coordinates: [ -97.654724, 30.210768 ]  }
} );
db.places.insert( {
   name: "Albuquerque",
   location: { type: "Point", coordinates: [ -106.621216, 35.113281 ]  }
} );

db.places.createIndex( { location: "2dsphere" } )

You can write the following query using the factor 1609.344 to convert miles to meter

db.places.find(
   {
     location:
       { $near:
          {
            $geometry: { type: "Point",  coordinates: [-97.9524, 30.3061 ] },
            $maxDistance: 20*1609.344 
          }
       }
   }
)

This query returns both Bee Cave,TX and Austin, TX:

{
   "_id":ObjectId("5a7190124f0cd7075d349bbc"),
   "name":"Bee Cave, Texas",
   "location":{
      "type":"Point",
      "coordinates":[
         -97.9524,
         30.3061
      ]
   }
}{
   "_id":ObjectId("5a7190124f0cd7075d349bbd"),
   "name":"Austin, Texas",
   "location":{
      "type":"Point",
      "coordinates":[
         -97.654724,
         30.210768
      ]
   }
}
like image 149
Alex Avatar answered Sep 10 '25 15:09

Alex