使用find()进行MongoDB地理空间查询

时间:2014-06-17 14:22:09

标签: mongodb geospatial

我有一些"loc"字段的文档如下所示:

mongos> db.foo.findOne()
{
    // ... some other stuff
    "loc" : {
            "type" : "Point",
            "coordinates" : [
                    -83.362342,
                    26.687779
            ]
    }
}

它的索引是这样的:

mongos> db.foo.getIndices()
[
    // ... some other stuff
    {
            "v" : 1,
            "key" : {
                    "loc" : "2dsphere"
            },
            "name" : "loc_2dsphere",
            "ns" : "amitest.foo",
            "2dsphereIndexVersion" : 2
    },
]

根据the docs,我应该能够像下面这样查询它,但是我收到了错误:

mongos> db.foo.find(
  {loc :
    {$near:
      {$geometry:
        {type: "Point",
         coordinates: [-83.362342, 26.687779]
        },
       $maxDistance: 100
      }
    }
  }
).limit(5)

error: { "$err" : "use geoNear command rather than $near query", "code" : 13501 }

可以 使用runCommand()成功查询该字段,但这并不理想,因为我无法将其与其他条件相结合:

mongos> db.runCommand(
  {geoNear : "foo", 
   near : {type : "Point",
           coordinates : [-83.362342, 26.687779]
          },
   spherical : true,
   maxDistance : 10,
   limit : 5
  }
)

我有一个带有8个分片的散列分片集合上的MongoDB 2.6.0。

1 个答案:

答案 0 :(得分:2)

geospatial index documentation中,它指出:"对于分片集合,不支持使用$ near的查询。您可以改为使用geoNear命令或$ geoNear聚合阶段。"

有一个与此相关的错误https://jira.mongodb.org/browse/SERVER-926,它被标记为已关闭,并且针对未来版本的MongoDB 1.7.2,它将使$ near运算符与分片集合一起使用。但是,请注意,有一个很大但是接近查询将通过mongos路由到所有分片,这可能是非常低效的。这是因为一般情况下地理列不支持分片,请参阅相关且仍然打开的错误https://jira.mongodb.org/browse/SERVER-1982

反过来,这与MongoDB使用geohashing将二维地理对象转换为可以使用B树索引的东西以及理论上可以用作分片键的东西相关联这一事实有关。 。这是一个难以解决的问题,就像geohash索引一样,对象非常接近,最终可能会有很远的哈希值,因此很难设计出既适合用作分片键的东西,又支持高效的地理空间查询,如$ near。有关geohashing的潜在问题的更多信息,请参阅Wikipedia geohash article中的限制部分。