Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does anyone know a working example of 2dsphere index in pymongo?

I'm trying to code up a script to do basic 2dsphere index operation mentioned here 2dsphere using pymongo.

I could not find any example to figure it out, this is my attempt so far:

from pymongo import GEOSPHERE
client=MongoClient('localhost',27017)
db=client['dbtest']
points=db['points']
points.create_index([("loc",GEOSPHERE)])
points.insert({"loc":[2 5]})
points.insert({"loc":[30,5]})
more points.insert

for doc in points.find({"loc" : {"$near": { "$geometry" : {"type":"Point","coordinates":[1,2]},"$maxDistance":20}}}):
     print doc

It gives the errorpymongo.errors.OperationFailure: database error: can't find special index: 2d for: { loc: { $near: { $geometry: { type: "Point", coordinates: [ 1, 2 ] }, $maxDistance: 20 } } }

like image 645
gizgok Avatar asked Jun 04 '13 01:06

gizgok


2 Answers

The 2dsphere (pymongo.GEOSPHERE) index type only works in MongoDB 2.4 and newer. You're also going to want to use GeoJSON format for your points. Finally, MongoDB's geo query operators are order sensitive, so you'll have to use SON when using options like $maxDistance. Here's an example using $near:

>>> c = pymongo.MongoClient()
>>> points = c.dbtest.points
>>> points.ensure_index([("loc", pymongo.GEOSPHERE)])
u'loc_2dsphere'
>>> points.insert({'loc': {'type': 'Point', 'coordinates': [40, 5]}})
ObjectId('51b0e508fba522160ce84c3a')
>>> for doc in points.find({"loc" : SON([("$near", { "$geometry" : SON([("type", "Point"), ("coordinates", [40, 5])])}), ("$maxDistance", 10)])}):
...     doc
... 
{u'loc': {u'type': u'Point', u'coordinates': [40, 5]}, u'_id': ObjectId('51b0e508fba522160ce84c3a')}
like image 73
Bernie Hackett Avatar answered Nov 05 '22 15:11

Bernie Hackett


In most recent versions I believe $maxDistance must be inside the $near operator:

from bson.son import SON
from pymongo import MongoClient

db = MongoClient()
latitude = 10
longitude = 20
max_distance = 1000 #meters    

query = {'loc': {'$near': SON([('$geometry', SON([('type', 'Point'), ('coordinates', [longitude, latitude])])), ('$maxDistance', max_distance)])}}

for doc in db.database_name.collection_name.find(query):
    print(doc)
like image 43
Miguel Sousa Avatar answered Nov 05 '22 14:11

Miguel Sousa