3

I am using mongodb-engine to access MongoDB from a Django project. Normal get, insert and update works quite well, but now would I like to use the geoNear functionality. I can just not figure out a way to call it from Django.

I have tried MyModel.objects.raw(...) and also MyModel.objects.raw_query(...), but the result is not really as expected.

The query will be something like this one (it works from the Mongo shell)

db.runCommand({ geoNear : "mymodel", near : [3, 0], spherical : true, maxDistance : 10 })

And the model uses MongoDBManager

class MyModel(model.Model):
    objects = MongoDBManager()
    ...

has anyone successfully tried that?

Thx Simon

Nicolas Cortot
  • 6,591
  • 34
  • 44
SimonSays
  • 10,867
  • 7
  • 44
  • 59

2 Answers2

3

I guess the use of the MongoDB db.runCommand(), which is needed for queries with geoNear, is just not possible with the current version of mongodb-enginge. I am using a raw_query with the normal near syntax now and convert the distance between the 2 lat/lon points myself to miles (and the other way around).

lat_lon_dist = distance_to_lat_long(dist_in_miles)
l = Listing.objects.raw_query({
                       'geo_location' : {
                                     '$maxDistance': lat_lon_dist,
                                     '$near' : { 'latitude': lat, 'longitude': lon },
                                     }
                       })
...
EARTH_RADIUS = { 
                'km': 6371, 
                'mi': 3959 
                }

''' returns the distance between two lat/lon points in miles or kilometers '''
def lat_lon_to_distance(lat1, lon1, lat2, lon2, unit='mi'):
    lat1 = math.radians(lat1)
    lon1 = math.radians(lon1)
    lat2 = math.radians(lat2)
    lon2 = math.radians(lon2)
    return math.acos(math.sin(lat1)*math.sin(lat2) + 
                  math.cos(lat1)*math.cos(lat2) *
                  math.cos(lon2-lon1)) * EARTH_RADIUS[unit];

'''
converts a distance in miles or kilometer to a difference between two lat/lon points
the result is just approximately!
'''
def distance_to_lat_long(distance, unit='mi'):
    return distance / math.radians(EARTH_RADIUS[unit])
SimonSays
  • 10,867
  • 7
  • 44
  • 59
1

You can get the PyMongo objects as described here http://django-mongodb.org/topics/lowerlevel.html#pymongo-level

Jonas H.
  • 2,331
  • 4
  • 17
  • 23
  • The thing is that I would like to use the geoNear command which is called with db.runCommand() compared to the "normal" queries that run with db.mycollection.find(). geoNear would return the distance to the center and would account for the round shape of the earth. see here: http://www.mongodb.org/display/DOCS/Geospatial+Indexing/#GeospatialIndexing-TheEarthisRoundbutMapsareFlat – SimonSays Aug 22 '12 at 07:27