djangomongodbgeolocationdjango-mongodb-engine

Using MongoDB runCommand with Django MongoDb-engine


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


Solution

  • 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])