首页/数据/NoSQL 速查/地理空间查询 $near / $geoWithin
MongoDB99 条

地理空间查询 $near / $geoWithin

基于 GeoJSON 或传统坐标对做距离与范围查询;$near 按距离近到远返回,$geoWithin 判断点是否落在区域内。

NoSQL 速查数据更新于 2026-10-13

地理空间查询的两类写法

MongoDB 的地理查询围绕两个索引类型展开:2dsphere 处理球面距离,支持 GeoJSON(点、线、多边形);2d 处理平面坐标,适合老式地图数据。查询操作符按意图分成两类:$near 按距离由近到远返回,$geoWithin 判断点是否落在指定区域内(不排序)。选之前先确认坐标存储格式与是否已有对应索引。

基本信息

索引类型2dsphere(球面,GeoJSON)/ 2d(平面,旧式坐标对)
$near距离排序,可配 $maxDistance、$minDistance,必须走地理索引
$geoWithin区域内查询(圆、矩形、多边形),结果不排序
$geoIntersects判断几何对象是否与目标相交,适合路线与围栏
聚合写法$geoNear 必须是聚合管道第一阶段,返回结果带距离字段
单位提醒GeoJSON 坐标下 $maxDistance 以米为单位;旧式坐标对单位不同,建议统一用 GeoJSON

典型使用场景

  • 附近的门店与网点:按距离排序并限制半径,$near 最直接
  • 配送范围判定:用多边形或圆做 $geoWithin,判断地址是否在服务区内
  • 电子围栏与路线匹配:路段与围栏相交判断用 $geoIntersects
  • 聚合带距离:需要在结果里带上距离值并与其他条件组合时用 $geoNear
  • 围栏内计数统计:区域内统计常配合聚合在数据库侧完成

建索引与查询

建索引与查询
// 坐标必须以 GeoJSON 形式存储,注意顺序是 [经度, 纬度]
db.stores.insertOne({ name: "门店A", loc: { type: "Point", coordinates: [121.47, 31.23] } })
db.stores.createIndex({ loc: "2dsphere" })

// 附近的点:按距离排序,限制 1 公里内
db.stores.find({
  loc: { $near: {
    $geometry: { type: "Point", coordinates: [121.47, 31.23] },
    $maxDistance: 1000
  } }
})

// 区域内的点:多边形(首尾点需闭合)
db.stores.find({ loc: { $geoWithin: { $geometry: {
  type: "Polygon",
  coordinates: [[[121.4,31.2],[121.5,31.2],[121.5,31.3],[121.4,31.3],[121.4,31.2]]]
} } } })

// 聚合形式:返回结果里带距离字段,便于排序展示
// db.stores.aggregate([{ $geoNear: { near: { type: "Point", coordinates: [121.47, 31.23] },
//   distanceField: "dist", maxDistance: 1000, spherical: true } }])

操作符对照

操作符作用使用限制
$near按距离由近到远排序必须有地理索引;不能与 $or 等部分操作符组合
$geoWithin点落在区域内,不排序结果无序,需要排序要在应用层处理
$geoIntersects几何相交判断需明确坐标参考系与几何类型
$maxDistance / $minDistance限制距离范围单位随坐标格式变化,GeoJSON 用米
$geoNear(聚合)带距离的输出与更多筛选能力必须是管道第一阶段
GeoJSON 的坐标顺序是 [经度, 纬度],与常见的「先纬度后经度」书写习惯相反;写反不会报错,只会得到相隔很远的结果,调试时先核对这一条。
缺少地理索引时 $near 会直接报错,$geoWithin 则退化为低效扫描:上线前确认索引存在,并注意球面索引与平面索引的选择会影响距离精度。

易错点

  • 坐标顺序写反成 [纬度, 经度]:查询不报错但结果荒谬,是地理查询最常见的问题来源
  • 对旧式坐标对与 GeoJSON 混用同一索引:距离单位与解释方式不一致,半径过滤失效
  • 指望 $geoWithin 返回有序结果:它只做包含判断,需要按距离排序时必须改用 $near 或 $geoNear
  • 多边形首尾点未闭合:几何校验失败或范围异常,构造坐标时要显式闭合环

数据来源与参考

  • MongoDB Manual: Geospatial Queries
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌