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 } } }
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')}
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With