问题
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 } } }
回答1:
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')}
回答2:
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)
回答3:
Given your collection is names geoid and your geojson object is named geometry...
import pymongo
geoid.create_index([("geometry", pymongo.GEOSPHERE)])
That should do it!
来源:https://stackoverflow.com/questions/16908675/does-anyone-know-a-working-example-of-2dsphere-index-in-pymongo