news 2026/2/27 23:29:10

Redis实现附近的人

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis实现附近的人

Redis 3.2版本以后,基于geohash和数据结构Zset提供了地理位置相关功能。通过上边两种mysql的实现方式发现,附近的人功能是明显的读多写少场景,所以用redis性能更会有很大的提升。

redis 实现附近的人功能主要通过Geo模块的六个命令。

GEOADD:将给定的位置对象(纬度、经度、名字)添加到指定的key;
GEOPOS:从key里面返回所有给定位置对象的位置(经度和纬度);
GEODIST:返回两个给定位置之间的距离;
GEOHASH:返回一个或多个位置对象的Geohash表示;
GEORADIUS:以给定的经纬度为中心,返回目标集合中与中心的距离不超过给定最大距离的所有位置对象;
GEORADIUSBYMEMBER:以给定的位置对象为中心,返回与其距离不超过给定最大距离的所有位置对象。

GEOADD key longitude latitude member [longitude latitude member ...] 如下: GEOADD hotel 119.98866180732716 30.27465803229662 酒馆

java中使用redis实现:

package com.demo.controller; import lombok.Data; import lombok.experimental.Accessors; import org.example.DemoRedisApplication; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.geo.*; import org.springframework.data.redis.connection.RedisGeoCommands; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import java.util.ArrayList; import java.util.List; @SpringBootTest(classes = DemoRedisApplication.class) public class Test1 { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate<String, Object> redisTemplate; @Test public void test1() { //save(); List<UserInfo> userInfos = nearBySearch(100, 116.397428, 39.90923); userInfos.forEach(System.out::println); } //GEO相关命令用到的KEY private final static String KEY = "user_info"; public boolean save() { List<UserInfo> list = new ArrayList<>(); list.add(new UserInfo().setName("张三").setLatitude(39.90923).setLongitude(116.397428)); list.add(new UserInfo().setName("王五").setLatitude(39.90923).setLongitude(26.397428)); list.add(new UserInfo().setName("赵六").setLatitude(19.90923).setLongitude(106.397428)); list.add(new UserInfo().setName("小二").setLatitude(9.90923).setLongitude(116.397428)); list.add(new UserInfo().setName("小三").setLatitude(69.90923).setLongitude(96.397428)); list.add(new UserInfo().setName("小四").setLatitude(39.90923).setLongitude(116.397428)); list.add(new UserInfo().setName("小五").setLatitude(69.90923).setLongitude(116.397428)); list.add(new UserInfo().setName("小六").setLatitude(59.90923).setLongitude(116.397428)); list.add(new UserInfo().setName("小七").setLatitude(79.90923).setLongitude(116.397428)); list.add(new UserInfo().setName("小八").setLatitude(9.90923).setLongitude(116.397428)); list.add(new UserInfo().setName("小九").setLatitude(32.90923).setLongitude(106.397428)); for (UserInfo userInfo : list){ Long flag = redisTemplate.opsForGeo().add(KEY, new RedisGeoCommands.GeoLocation<>( userInfo.getName(), new Point(userInfo.getLongitude(), userInfo.getLatitude())) ); } return true; /*Long flag = redisTemplate.opsForGeo().add(KEY, new RedisGeoCommands.GeoLocation<>( userInfo.getName(), new Point(userInfo.getLongitude(), userInfo.getLatitude())) ); return flag != null && flag > 0;*/ } /** * 根据当前位置获取附近指定范围内的用户 * @param distance 指定范围 单位km ,可根据{@link org.springframework.data.geo.Metrics} 进行设置 * @param userLng 用户经度(-180,180) * @param userLat 用户纬度(-90,90) * @return */ public List<UserInfo> nearBySearch(double distance, double userLng, double userLat) { List<UserInfo> users = new ArrayList<>(); // 1.GEORADIUS获取附近范围内的信息 GeoResults<RedisGeoCommands.GeoLocation<Object>> reslut = redisTemplate.opsForGeo().radius(KEY, new Circle(new Point(userLng, userLat), new Distance(distance, Metrics.KILOMETERS)), RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs() .includeDistance() .includeCoordinates().sortAscending()); //2.收集信息,存入list List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> content = reslut.getContent(); //3.过滤掉超过距离的数据 content.forEach(a-> { users.add( new UserInfo() .setName(a.getContent().getName().toString()) .setDistance(a.getDistance().getValue()) .setLatitude(a.getContent().getPoint().getX()) .setLongitude(a.getContent().getPoint().getY())); }); return users; } @Data @Accessors(chain = true) public static class UserInfo{ private String name;// 酒店 private double latitude;// 用户经度(-180,180) private double longitude;// 用户纬度(-90,90) private double distance;// 距离 } }

测试一下ok了,还可以使用 mongdb来实现。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/20 16:34:28

大模型转行终极指南:4大方向+真实案例+项目实战,建议收藏

大模型转行终极指南&#xff1a;4大方向真实案例项目实战&#xff0c;建议收藏 本文分享2025年普通人转向大模型的实战经验。强调大模型是产业链而非单一岗位&#xff0c;新人应避免三大误区&#xff1a;盲目调参、只学名词不懂体系、工程能力弱。文章详细分析了4个适合不同背…

作者头像 李华
网站建设 2026/2/27 5:32:31

基于微信小程序的校园电子请假系统毕设

博主介绍&#xff1a;✌ 专注于Java,python,✌关注✌私信我✌具体的问题&#xff0c;我会尽力帮助你。一、研究目的本研究旨在设计并实现一款基于微信小程序的校园电子请假系统&#xff0c;以提升校园管理效率&#xff0c;优化学生请假流程。具体研究目的如下&#xff1a;提高校…

作者头像 李华
网站建设 2026/2/17 4:24:03

国家专精特新小巨人补贴,申报条件

一、国家专精特新小巨人补贴1、资金扶持&#xff1a;每户给予一次性100万奖补&#xff08;以各地方具体奖补金额为准&#xff09;。2、荣誉资质&#xff1a;颁发“国家专精特新小巨人”企业证书。3、政策帮助&#xff1a;重点对企业发展中遇到的困难&#xff0c;是“一企一策”…

作者头像 李华
网站建设 2026/2/27 6:28:31

GraniStudio零代码平台主任务设计器如何快速定位算子?

GraniStudio平台快速定位算子分两方面&#xff0c;一方面使用算子库查找&#xff0c;另一方面通过功能窗口查找。 算子库查找是编程时需要使用某个功能时通过输入算子名称查找相应算子或者控件&#xff0c;方便编程使用&#xff0c;在平台资源管理器、主任务设计器、HMI界面都支…

作者头像 李华
网站建设 2026/2/26 5:10:44

学网络安全需要会编程吗?

如今数据泄露、网络攻击频发&#xff0c;企业对安全人才的需求只增不减&#xff0c;不仅就业机会多&#xff0c;职业生命周期也更长&#xff0c;越有经验越吃香&#xff0c;完全不用担心35岁危机。那么学网络安全需要会编程吗?具体请看下文。学网络安全需要会编程吗?学网络安…

作者头像 李华
网站建设 2026/2/21 23:22:57

B站UP主招募:制作LobeChat测评视频享补贴

LobeChat&#xff1a;当开源遇上大模型&#xff0c;如何打造属于你的AI对话门户&#xff1f; 在大语言模型几乎每周都在刷新性能记录的今天&#xff0c;一个有趣的现象逐渐浮现&#xff1a;我们手握越来越强大的“大脑”——GPT-4、Claude 3、Qwen、ChatGLM……但让这些大脑真正…

作者头像 李华