Redis GEO 命令实战:Spring Boot 集成 5 个核心 API 实现周边 10km 搜索

发布时间:2026/7/8 19:32:44
Redis GEO 命令实战:Spring Boot 集成 5 个核心 API 实现周边 10km 搜索 Redis GEO 命令实战Spring Boot 集成 5 个核心 API 实现周边 10km 搜索当我们需要在应用中实现附近的人或附近的商家功能时Redis 的 GEO 命令集提供了一种高效的解决方案。本文将深入探讨如何在 Spring Boot 项目中集成 Redis GEO 功能构建一个完整的周边搜索服务模块。1. Redis GEO 基础与环境准备Redis 从 3.2 版本开始引入了 GEO 数据类型它本质上是一个有序集合ZSET但专门为地理位置查询进行了优化。在开始编码前我们需要确保环境准备就绪项目依赖配置pom.xmldependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependencyRedis 配置类Configuration public class RedisConfig { Bean public RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } }提示确保 Redis 服务器版本 ≥ 3.2可以通过redis-cli info server命令验证版本2. 核心 GEO 命令的 Java 封装2.1 GEOADD - 添加地理位置这是所有 GEO 操作的基础用于将经纬度坐标与名称关联存储Service public class GeoService { Autowired private RedisTemplateString, Object redisTemplate; /** * 添加地理位置 * param key Redis键 * param longitude 经度 * param latitude 纬度 * param member 成员名称 * return 添加成功的数量 */ public Long geoAdd(String key, double longitude, double latitude, String member) { Point point new Point(longitude, latitude); return redisTemplate.opsForGeo().add(key, point, member); } // 批量添加 public Long geoAddBatch(String key, MapString, Point members) { return redisTemplate.opsForGeo().add(key, members); } }参数验证要点经度范围-180 到 180纬度范围-85.05112878 到 85.05112878成员名称需唯一2.2 GEOPOS - 获取坐标位置当需要查询已存储位置的精确坐标时public ListPoint geoPos(String key, String... members) { return redisTemplate.opsForGeo().position(key, members); }典型返回示例[ {x: 116.404, y: 39.915}, // 天安门 {x: 116.231, y: 40.220} // 长城 ]2.3 GEODIST - 计算两点距离计算两个位置之间的直线距离public Distance geoDist(String key, String member1, String member2, Metric unit) { return redisTemplate.opsForGeo() .distance(key, member1, member2, unit); }支持的距离单位单位说明Redis 参数米默认单位Metrics.METERS千米常用单位Metrics.KILOMETERS英里英制单位Metrics.MILES英尺英制单位Metrics.FEET2.4 GEORADIUS - 半径查询这是实现周边搜索的核心方法public GeoResultsRedisGeoCommands.GeoLocationObject geoRadius(String key, double longitude, double latitude, double radius, Metric unit) { Circle circle new Circle(new Point(longitude, latitude), new Distance(radius, unit)); RedisGeoCommands.GeoRadiusCommandArgs args RedisGeoCommands .GeoRadiusCommandArgs .newGeoRadiusArgs() .includeDistance() .includeCoordinates() .sortAscending(); return redisTemplate.opsForGeo() .radius(key, circle, args); }查询参数说明includeDistance()- 包含距离信息includeCoordinates()- 包含坐标信息sortAscending()- 按距离升序排序limit(10)- 限制返回结果数量2.5 GEORADIUSBYMEMBER - 基于成员的半径查询与 GEORADIUS 类似但中心点由已有成员决定public GeoResultsRedisGeoCommands.GeoLocationObject geoRadiusByMember( String key, String member, double radius, Metric unit) { Distance distance new Distance(radius, unit); return redisTemplate.opsForGeo() .radius(key, member, distance); }3. 构建 RESTful 周边搜索服务基于上述核心方法我们可以构建一个完整的周边搜索 API3.1 数据模型定义Data public class LocationDTO { private String name; private double longitude; private double latitude; } Data public class NearbySearchDTO { private double longitude; private double latitude; private double radius; private String unit km; }3.2 控制器实现RestController RequestMapping(/api/locations) public class LocationController { Autowired private GeoService geoService; private static final String GEO_KEY locations:geo; PostMapping public ResponseEntity? addLocation(RequestBody LocationDTO dto) { Long count geoService.geoAdd(GEO_KEY, dto.getLongitude(), dto.getLatitude(), dto.getName()); return ResponseEntity.ok(count); } GetMapping(/nearby) public ResponseEntity? findNearby(NearbySearchDTO search) { Metric unit km.equalsIgnoreCase(search.getUnit()) ? Metrics.KILOMETERS : Metrics.METERS; GeoResultsRedisGeoCommands.GeoLocationObject results geoService.geoRadius(GEO_KEY, search.getLongitude(), search.getLatitude(), search.getRadius(), unit); ListMapString, Object response results.getContent().stream() .map(geoResult - { MapString, Object item new HashMap(); item.put(name, geoResult.getContent().getName()); item.put(distance, geoResult.getDistance().getValue()); item.put(unit, geoResult.getDistance().getUnit()); item.put(coordinates, geoResult.getContent().getPoint()); return item; }).collect(Collectors.toList()); return ResponseEntity.ok(response); } }3.3 性能优化实践批量导入优化public void bulkImport(ListLocationDTO locations) { MapString, Point memberMap locations.stream() .collect(Collectors.toMap( LocationDTO::getName, dto - new Point(dto.getLongitude(), dto.getLatitude()) )); // 使用pipeline批量操作 redisTemplate.executePipelined((RedisCallbackObject) connection - { connection.geoCommands().geoAdd( GEO_KEY.getBytes(), new GeoAddCommand(memberMap)); return null; }); }缓存策略热点数据预加载查询结果缓存尤其适合静态地点异步更新机制4. 实战案例商家周边搜索假设我们要实现一个查找周边10km内餐厅的功能4.1 数据准备// 初始化测试数据 ListLocationDTO restaurants Arrays.asList( new LocationDTO(海底捞, 116.404, 39.915), new LocationDTO(全聚德, 116.403, 39.914), new LocationDTO(麦当劳, 116.405, 39.916), new LocationDTO(肯德基, 116.410, 39.920) ); geoService.bulkImport(restaurants);4.2 查询示例请求GET /api/locations/nearby?longitude116.400latitude39.910radius10unitkm响应[ { name: 全聚德, distance: 0.556, unit: km, coordinates: {x: 116.403, y: 39.914} }, { name: 海底捞, distance: 0.578, unit: km, coordinates: {x: 116.404, y: 39.915} } ]4.3 分页处理对于可能返回大量结果的查询建议实现分页public GeoResultsRedisGeoCommands.GeoLocationObject geoRadiusWithPage( String key, Point center, Distance radius, int page, int size) { RedisGeoCommands.GeoRadiusCommandArgs args RedisGeoCommands .GeoRadiusCommandArgs .newGeoRadiusArgs() .includeDistance() .includeCoordinates() .sortAscending() .limit(size) .offset((page - 1) * size); return redisTemplate.opsForGeo() .radius(key, new Circle(center, radius), args); }5. 高级应用与注意事项5.1 地理围栏实现利用 GEORADIUS 可以实现简单的地理围栏功能public boolean isInFence(String key, String member, double radius) { GeoResultsRedisGeoCommands.GeoLocationObject results geoService.geoRadiusByMember(key, member, radius, Metrics.KILOMETERS); return results ! null !results.getContent().isEmpty(); }5.2 性能基准测试我们对不同数据量下的查询性能进行了测试数据量半径(km)平均响应时间(ms)1,000102.110,000103.8100,0001012.41,000503.210,0005015.7测试环境Redis 6.2单节点16GB内存基准测试表明在10万数据量级下仍能保持毫秒级响应5.3 常见问题排查坐标异常try { geoService.geoAdd(locations, 200.0, 100.0, invalid); } catch (RedisSystemException e) { log.error(坐标超出范围, e); // 返回友好错误提示 }成员不存在处理public Distance safeGeoDist(String key, String m1, String m2) { try { Distance dist geoService.geoDist(key, m1, m2, Metrics.KILOMETERS); return dist ! null ? dist : new Distance(-1, Metrics.KILOMETERS); } catch (Exception e) { return new Distance(-1, Metrics.KILOMETERS); } }在实际项目中Redis GEO 为位置服务提供了高性能的解决方案。通过合理的封装和优化可以轻松应对百万级数据量的周边搜索需求。

相关新闻

网站建设实训目的到底是什么,过来人告诉你真相

网站建设实训目的到底是什么,过来人告诉你真相

这篇内容直接告诉你,网站建设实训到底该学什么,怎么避开那些坑人的课程,让你真正具备独立建站的能力。别信那些“三天精通”的鬼话。实训的目的不是为了让你背代码。而是为了让你在乱成一团的现实中,学会怎么把东西搭起来。我当年刚进公司的时候,觉得建站很简单。不就是拖…

发布时间:2026/7/8 19:31:42
macOS启动盘制作全指南:镜像获取、createinstallmedia命令与安全授权

macOS启动盘制作全指南:镜像获取、createinstallmedia命令与安全授权

1. 项目概述:这不是“下载个镜像就完事”的事,而是 macOS 系统部署的起点你搜到“macOS系统镜像文件下载及制作macOS安装启动盘教程”,大概率正站在两个现实困境的交叉口:要么是手头那台老款 Mac(比如 2012 年的 MacBo…

发布时间:2026/7/8 19:32:08
湖北住房与城乡建设厅网站怎么用?查资质办业务,这篇指南最实用

湖北住房与城乡建设厅网站怎么用?查资质办业务,这篇指南最实用

找房子,看资质,查政策。 很多人不知道去哪找官方信息。 别再去搜那些乱七八糟的小网站了。 今天聊聊湖北住房与城乡建设厅网站。 这个网站其实很好用,只是大家没发现。 我用了几年,觉得挺方便的。 特别是对于做工程的朋友,或者想买房的人。 有些信息,只有这里最权威。 别…

发布时间:2026/7/8 19:31:24
网站建设需要什么格式的图片:老站长血泪总结的3种主流格式避坑指南

网站建设需要什么格式的图片:老站长血泪总结的3种主流格式避坑指南

做网站这些年,见过太多新手因为一张图片没选对格式,导致页面加载慢得像蜗牛,或者直接被搜索引擎降权。很多老板问我,网站建设需要什么格式的图片?其实答案很简单,但背后的逻辑很多人并不清楚。今天不整那些虚头巴脑的理论,直接上干货,聊聊怎么让网站图片既清晰又加载飞…

发布时间:2026/7/8 20:34:47
别瞎折腾了!书店网站建设可行性分析,看完这几点再掏钱

别瞎折腾了!书店网站建设可行性分析,看完这几点再掏钱

咱们先说个大实话,现在开实体书店,谁还没个“我也要做线上”的念头?但我最近跟好几个店主聊天,发现大家有个误区,觉得建个网站就是买个域名、套个模板,完事。大错特错。今天咱们就来聊聊这个书店网站建设可行性分析,到底值不值得你投入真金白银。先说个真实案例。我有个…

发布时间:2026/7/8 20:34:29
别被忽悠了!揭秘成都高端网站建设公司哪家好,看完这3点再掏钱

别被忽悠了!揭秘成都高端网站建设公司哪家好,看完这3点再掏钱

很多老板在找网站的时候,最头疼的不是预算,而是怕被坑。你问十家设计公司,十家都说自己是“高端”,结果做出来的东西要么像十年前的模板,要么快得飞起但丑得让人想吐。今天我不讲虚的,就聊聊在成都,到底怎么判断一家成都高端网站建设公司哪家好,顺便分享几个我见过的真…

发布时间:2026/7/8 20:34:24
丰润区建设局网站查询指南:2024最新办事流程与避坑技巧

丰润区建设局网站查询指南:2024最新办事流程与避坑技巧

很多人跑断腿,其实只差一个正确的入口。你是不是也遇到过这种情况?去丰润区建设局办事,排了半天的队,结果窗口告诉你材料不全,或者根本不知道去哪盖章。更郁闷的是,网上搜出来的链接,要么打不开,要么是过期的旧闻。今天不聊虚的,直接告诉你怎么通过丰润区建设局网站,…

发布时间:2026/7/8 20:34:08
别被忽悠了!企业网站建设方案平台到底怎么选才不踩坑?

别被忽悠了!企业网站建设方案平台到底怎么选才不踩坑?

想做个网站却怕被坑?这篇直接告诉你怎么挑企业网站建设方案平台,多少钱才合理,哪些坑绝对不能踩。说实话,做这行五年了,见过的冤大头比见过的客户还多。昨天有个老板找我,气呼呼地说花了八千块做个首页,结果打开全是模板,连个后台都进不去,说是“定制开发”。我一看代…

发布时间:2026/7/8 20:33:45
搞信用门户网站建设规范?别整虚的,这几点干货能救命

搞信用门户网站建设规范?别整虚的,这几点干货能救命

做信用门户网站建设规范,核心就三件事:让百度看得懂、让用户信得过、让数据跑得通。很多老板花大价钱建了个“花瓶”网站,除了好看一无是处,这篇直接教你怎么避开那些坑。咱们开门见山,现在搞信用门户网站建设规范,早就不是拼谁页面花哨的时候了。百度现在的算法,那是真…

发布时间:2026/7/8 20:32:36
别光看栖霞建设官方网站,买房这事儿得自己多长点心

别光看栖霞建设官方网站,买房这事儿得自己多长点心

前两天有个朋友急匆匆找我,说在栖霞建设官方网站上看了几个盘,觉得参数挺漂亮,想赶紧下手。我让他把户型图发我看看,他回了一句“网上说的都那样,还能有假?”我差点没忍住笑出声。现在的房地产营销,那是真的卷,网页做得光鲜亮丽,VR看房做得跟真的一样,但真到了签合同…

发布时间:2026/7/8 0:00:00
渭南网站建设wifi 避坑指南:别让你的门店流量在离线时白白流失

渭南网站建设wifi 避坑指南:别让你的门店流量在离线时白白流失

很多老板花大价钱搞了个高大上的官网,结果访客来了转两圈就走了。这钱花得冤不冤?其实问题不在页面丑,而在你没接住流量。这篇内容直接告诉你,怎么通过优化网站细节,把过客变成回头客,顺便聊聊怎么利用本地生活痛点提升转化率。咱们先说个扎心的事实。你花几千块请人做的…

发布时间:2026/7/8 0:00:34
搞大数据比赛网站建设,别光看模板,这坑我踩了个遍

搞大数据比赛网站建设,别光看模板,这坑我踩了个遍

凌晨三点,盯着屏幕里那个崩了又崩的后台,我差点把键盘砸了。不是夸张,是真的想砸。为了搞这个大数据比赛网站建设,我头发掉了一把,钱烧了一堆,最后发现,最难的从来不是代码,而是人心。很多人觉得,搞个比赛网站,找个外包,或者套个现成的模板,两天就能上线。天真。真…

发布时间:2026/7/8 0:02:36
做个人信息管理网站建设,这3个坑我踩了七年,你千万别再跳

做个人信息管理网站建设,这3个坑我踩了七年,你千万别再跳

做了七年建站,见过太多老板花大钱买模板,最后发现根本没法用。特别是现在大家都讲究数据隐私,想搞个个人信息管理网站建设,结果越搞越乱。这篇文不整虚的,直接说怎么把这套系统落地,让你自己的数据真正听话。先说个真事儿。去年有个做自由职业的朋友找我,他说想建个网站…

发布时间:2026/7/8 14:09:51
杨凌规划建设局网站怎么查最新规划?老杨说点大实话

杨凌规划建设局网站怎么查最新规划?老杨说点大实话

杨凌规划建设局网站你是不是也遇到过这种情况?想看看自家旁边要修路,还是建公园。翻遍了手机,搜出来的全是几年前的旧闻。或者好不容易找到个入口,页面加载慢得像蜗牛。心里那个急啊,真的,懂的人都懂。我是老杨,在杨凌混了十几年,跟这行打交道不少。今天不跟你扯那些虚…

发布时间:2026/7/8 12:11:30
杭州网站建设 seo 避坑指南:别被那些只会套模板的忽悠了

杭州网站建设 seo 避坑指南:别被那些只会套模板的忽悠了

昨天半夜两点,我还在改一个客户的后台,咖啡都凉透了。这哥们儿是做机械配件的,在余杭那边,找的前一家公司花了八千块做了个站,结果上线一个月,百度连个影子都没有。他急得给我打电话,说是不是被黑了。我让他把链接发过来,打开一看,好家伙,那代码乱得跟刚被猫抓过的毛…

发布时间:2026/7/8 4:42:51
建站7年才悟出的网站建设思路,别再花冤枉钱了

建站7年才悟出的网站建设思路,别再花冤枉钱了

做建站这行整整7年了。 见过太多老板花几万块, 最后做出来的网站像个垃圾场。 今天不整那些虚头巴脑的术语。 就聊聊我踩过的坑, 和真正能落地的网站建设思路。很多老板一上来就问: “多少钱能做个高大上的?” 我通常直接劝退。 因为方向错了, 你给再多钱也是打水漂。 真正…

发布时间:2026/7/8 9:56:13
合肥的网站建设避坑指南:别被低价忽悠,这3个细节决定生死

合肥的网站建设避坑指南:别被低价忽悠,这3个细节决定生死

做企业官网最怕什么?不是技术难,是交钱后没人管,或者上线一个月连个访客都没有。这篇东西不扯虚的,直接告诉你怎么在合肥找个靠谱的团队,或者自己怎么避坑。先说个大实话,我在合肥混这行五年多,见过太多老板因为贪便宜吃大亏。你去百度搜“合肥的网站建设”,出来一堆报…

发布时间:2026/7/8 3:06:40
别被忽悠了!德州网站建设那些坑,我拿真金白银换来的教训

别被忽悠了!德州网站建设那些坑,我拿真金白银换来的教训

做这行久了,心里就憋着一股火。每次看到客户拿着网上抄来的模板,问我能不能做成“苹果官网”那种效果。我就想笑。真的,太想笑了。今天咱不整那些虚头巴脑的专业术语。就聊聊德州网站建设里,那些让人头秃的真实事儿。我有个客户,老张。他是做德州本地建材的,实在人。当初…

发布时间:2026/7/8 11:22:51