当前位置: 首页 > news >正文

使用MongoDB存储和计算距离

一、MongoDB 计算距离的优势

优势说明
原生地理空间索引支持 2dsphere 索引,高效处理地理坐标查询(毫秒级响应)。
内置地理计算函数提供 $near$geoWithin$geoNear 等操作符,无需手动实现复杂计算。
高性能基于B树索引优化,海量数据下仍能快速返回结果(如亿级点位数据)。
灵活的数据模型直接存储GeoJSON格式坐标,支持点、线、多边形等复杂地理形状。
与Spring生态集成通过Spring Data MongoDB可简化开发。

二、实现步骤(Spring Boot + MongoDB)

1. 添加依赖

略,可参照前面MongoDB的博客。

2.定义地理位置实体

存储带有经纬度的文档(以“商家”为例):

import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
import org.springframework.data.mongodb.core.mapping.Document;@Document(collection = "places")
@Data
public class Place {private String id;private String name;@GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE) // 关键:创建地理空间索引private GeoJsonPoint location; // 格式: { type: "Point", coordinates: [经度, 纬度] }}
3. 初始化地理空间索引

确保集合已创建 2dsphere 索引(若未自动创建,可手动执行):

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.GeospatialIndex;@PostConstruct
public void initIndex() {mongoTemplate.indexOps(Place.class).ensureIndex(new GeospatialIndex("location"));
}
4. 实现距离查询
场景1:查询附近5公里内的商家(按距离排序)
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;public List<Place> findNearbyPlaces(double longitude, double latitude, double maxDistanceKm) {Point userLocation = new Point(longitude, latitude);Distance distance = new Distance(maxDistanceKm, Metrics.KILOMETERS);NearQuery nearQuery = NearQuery.near(userLocation).maxDistance(distance).spherical(true); // 使用球面几何计算return mongoTemplate.find(new Query(Criteria.where("location").nearSphere(userLocation).maxDistance(distance.getNormalizedValue())),Place.class);
}
场景2:查询多边形区域内的点位
import org.springframework.data.geo.Polygon;public List<Place> findWithinPolygon(List<Point> polygonPoints) {return mongoTemplate.find(Query.query(Criteria.where("location").within(new Polygon(polygonPoints))),Place.class);
}

三、MongoDB地理查询原理解析

  1. 索引类型

    • 2dsphere:支持球面几何计算(地球曲率),适合真实地理场景。

    • 2d:平面计算(简化模型),适用于小范围地图(如游戏地图)。

  2. 距离算法
    MongoDB默认使用 Haversine公式 计算球面距离,精度高。

  3. 性能对比

    • MySQL:需手动计算 ST_Distance_Sphere,无专用索引,性能随数据量下降。

    • MongoDB:利用地理索引,查询时间稳定在毫秒级。

四、注意事项

  1. 坐标格式标准化

    • 始终使用 [经度, 纬度] 顺序(GeoJSON标准),避免混淆。

    • 示例:new GeoJsonPoint(116.404, 39.915)(北京天安门)。

  2. 单位一致性

    • MongoDB默认返回距离单位为米,需在业务层统一转换(如公里/英里)。

  3. 分页优化

NearQuery.near(userLocation).maxDistance(distance).skip(20) // 跳过前20条.limit(10); // 每页10条

http://www.dtcms.com/a/324493.html

相关文章:

  • Spring Boot 2 升级 Spring Boot 3 的全方位深度指南
  • Leetcode 3644. Maximum K to Sort a Permutation
  • 9_基于深度学习的车型检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • Error: error:0308010C:digital envelope routines::unsupported at new Hash
  • 【Python 小脚本·大用途 · 第 3 篇】
  • 编译xformers
  • 【深度学习新浪潮】遥感图像风格化迁移研究工作介绍
  • 学习记录(十九)-Overleaf如何插入图片(单,多)
  • 学习模板元编程(3)enable_if
  • CART算法:Gini指数
  • 25.机器学习入门:让机器变聪明的魔法课
  • 串口通信初始化过程是怎样的???
  • IDEA 快捷编辑指南
  • Java开源代码源码研究:我的成长之路与实战心得分享
  • IDEA 安装插件的两种方式
  • 【面试场景题】异地多活改造方案
  • AI大模型--提示词工程
  • CVPR医学图像三套创新方案:通用分割+3D高效解码+SSM肿瘤定位(附链接)
  • 如何解决网站长期不连接数据库后首次连接缓慢的问题?
  • JS--判断是对象还是数组
  • Spring之【详解AOP】
  • 使用 Docker-Compose 部署 Redis 三主三从集群(含 Exporter 监控)
  • SQL Server从入门到项目实践(超值版)读书笔记 23
  • Windows 11 安装 JDK 11
  • ThreadLocal的原理是什么,使用场景有哪些?
  • 【自动化运维神器Ansible】playbook案例解析:Handlers与Notify机制深度解析
  • Vue3入门到精通:2.4 Vue3动态组件与异步组件深度解析
  • leetcode经典题目——单调栈
  • 【Python 工具人快餐 · 第 7 份 · 完结】
  • Redis 监控与优化方案(C++项目)