【问题标题】:Does anyone know a working example of 2dsphere index in pymongo?有人知道 pymongo 中 2dsphere 索引的工作示例吗?
【发布时间】:2018-01-19 13:35:24
【问题描述】:

我正在尝试编写一个脚本来执行这里提到的基本 2dsphere 索引操作 2dsphere 使用 pymongo。

我找不到任何例子来解决这个问题,这是我迄今为止的尝试:

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

它给出了错误pymongo.errors.OperationFailure: database error: can't find special index: 2d for: { loc: { $near: { $geometry: { type: "Point", coordinates: [ 1, 2 ] }, $maxDistance: 20 } } }

【问题讨论】:

  • 您的尝试正在我的机器上运行,但我已将 maxDistance 设置为一个非常大的数字。您使用的是哪个 MongoDB 版本?我正在使用 MongoDB 2.4.3。

标签: python mongodb pymongo


【解决方案1】:

2dsphere (pymongo.GEOSPHERE) 索引类型仅适用于 MongoDB 2.4 及更高版本。您还需要使用GeoJSON 格式作为您的积分。最后,MongoDB 的地理查询运算符对顺序敏感,因此在使用 $maxDistance 等选项时必须使用SON。这是一个使用$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.4.4。我相信那是我使用的版本。
  • 但是这个例子没有使用 2dsphere 查询。
【解决方案2】:

在最近的版本中,我相信$maxDistance 必须在$near 运算符内:

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)

【讨论】:

  • 建立2dsphere索引,这个查询过滤器是正确的
【解决方案3】:

假设您的集合名称为 geoid,而您的 geojson 对象名称为几何...

import pymongo

geoid.create_index([("geometry", pymongo.GEOSPHERE)])

应该这样做!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    相关资源
    最近更新 更多