Does anyone know a working example of 2dsphere ind

2019-04-29 04:12发布

问题:

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!