如何在MongoDB 2.4的2d或2dsphere索引字段上使用常规查询

时间:2016-04-04 19:38:51

标签: python mongodb mongodb-query pymongo geospatial

我有一个带有遗留坐标对的地理空间mongodb作为Geo2D索引。从这个数据库中我想提取一个位置列表(遗留坐标对)。对于普通列,我可以使用" $ in"查询可能的对列表,如下所示。

>>> db.collection.find_one({'country': {'$in': ['Argentina', 'Chile']}})

我不知道如何在loc列上执行此操作。 loc列上的类似操作会引发错误

>>> db.collection.find_one({'loc': {'$in': [(-35, 20), (-30, 21)]}})

geo field only has 1 element :: caused by :: $in: [ [ -35, 20 ], [ -30, 21 ] ]

我想到的解决方案是分别匹配列表中的每个成员。然而,它可能不是最有效的解决方案。我可以做一个聚合/地图减少技巧吗?

相关信息

db看起来像:

>>> db.collection.find_one()

{u'value': 2.7062699269224995,
 u'_id': ObjectId('56cf807e54013b935b88d3da'),
 u'country': u'Algeria',
 u'date': datetime.datetime(2015, 1, 1, 0, 0),
 u'iso2': u'DZ',
 u'lat': 27.0,
 u'loc': [27.0, -8.0],
 u'lon': -8.0,
 u'place': u'27.0_-8.0_DZ'}

索引键是:

[ { "_id" : 1 }, { "date" : -1 }, { "loc" : "2d" } ]

1 个答案:

答案 0 :(得分:1)

这里的问题是服务器版本是MongoDB 2.4.x系列。在MongoDB 2.6.x之前,“地理空间”索引的查询引擎处理是针对标准查询单独完成的,因此通过请求常规$in表达式而不是$near等地理空间操作,由于该字段已应用"2d"地理空间索引,因此查询发生在无法处理表达式的引擎的一部分中。

所以MongoDB 2.4.x“无法”使用常规查询操作的地理空间索引。如果您“需要”为查询使用“索引”,则“必须”在查询中引用的字段上使用.ensure_index()创建常规索引:

db.collection.ensure_index({ "loc": 1 })

请注意,这是已经应用的“2d”索引的“添加”。由于索引具有不同的“类型”,因此它们被单独命名和存在。所以两者都没有问题。

替代方法是使用.hint()说明符在光标上$natural强制进行“集合扫描”,因此“忽略”地理空间索引。

从MongoDB 2.6.x及更高版本开始,查询引擎是统一的,此处的限制不适用。根据给定的查询,可能不会使用“地理空间”索引,除非您再次指定.hint()以明确选择该索引以供使用。但它会毫无问题地运作。

作为最后一点,MongoDB 2.6.x及更高版本允许在以GeoJSON格式存储的数据上创建“地理空间”索引。即:

"location": {
    "type": "Point",
    "coordinates": [27.0, -8.0]
}

由于此示例中的索引位于"location"字段,而不是直接位于"location.coordinates"数组上,因此$in查询无法识别{{}上的“索引” 1}}可用于匹配数组内容的普通查询。在这种情况下,您将再次在"location"上直接创建一个普通索引,以允许查询使用该“索引”。