MongoDB——地理空间索引

639 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情

在移动互联网时代,基于地理位置的检索(LBS)功能几乎是所有应用系统的标配。MongoDB为地理空间检索提供了非常方便的功能。

2d 索引

存储为二维平面上的点的数据使用该索引。适用于MongoDB 2.2及更早版本中使用的旧坐标。适用版本已经很古老了,非必要,不推荐使用

geoHaystack索引

geoHaystack索引是一种特殊索引,经过优化以返回小范围内的结果。geoHaystack索引提高了使用平面几何的查询的性能。

对于使用球面几何的查询,2dsphere 索引是比 haystack 索引更好的选择。2dsphere允许字段重新排序;geoHaystack索引要求第一个字段是位置字段。此外,geoHaystack 索引只能通过命令使用,因此总是一次返回所有结果。

但是在MongoDB 5.0中被删除geoHaystack索引和geoSearch 命令,所以也不推荐使用。

2dSphere 索引

该索引支持计算类地球体上的查询。并支持所有MongoDB地理空间查询:包含,交叉和临近查询。并且支持存储GeoJSON和旧坐标对的数据。对于旧坐标对,索引将数据转换为GeoJSON Point。相比较而言,这种索引方式是目前最优的一种方案。

注意事项:

  • 管道操作需要指定一个key表示使用的索引字段,$geoNear允许有多个索引。
  • 不能作为分片键
  • 索引字段必须是坐标对或GeoJSON形式存在
  • 索引数量有限。生成内部索引可能是一大堆数据(因为是数组的形式,对于复合索引,会有笛卡尔积存在)。indexMaxNumGeneratedKeysPerDocument限制为单个文档生成的最大键数,以防止内存不足错误。默认值为每个文档 100000 个索引键。可以提高限制,但如果操作需要的键数超过indexMaxNumGeneratedKeysPerDocument参数指定的数量,则操作将失败。

创建索引

要创建2dsphere索引,字符串文字指定"2dsphere"为索引类型:

db.<collection>.createIndex( { <location field> : "2dsphere" } )

使用

MongoDB如何实现“查询附近商家"?

假设有以下数据:

db.restaurant.insert({
  restaurantId: 0,
  restaurantName: "兰州牛肉面",
  location: { type: "Point", coordinates: [ -73.97, 40.77] }
})

创建索引

db.restaurant.createIndex({location : "2dsphere"})

查询附近10000米商家信息

db.restaurant.find({
  location: {
    $near: {
      $geometry:{
        $type: "Point",
        coordinates: [-73.88, 40.78]
      },
      $maxDistance: 10000
    }
  }
})
  • $near查询操作符,用于实现附近商家的检索,返回数据结果会按距离排序。
  • $geometry操作符用于指定一个GeoJSON格式的地理空间对象,type=Point

示地理坐标点,coordinates则是用户当前所在的经纬度位置;$maxDistance限定

了最大距离,单位是米。