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

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来实现。

http://www.cnnetsun.cn/news/95066.html

相关文章:

  • 基于微信小程序的校园电子图书馆系统毕业设计
  • 创新首发!基于VMD+WDCNN-SENet的故障诊断模型
  • Python好不好学?
  • NAS 部署私人云平台,支持扩展only office等办公应用
  • Linux EEPROM调试
  • 终极解决方案:告别Visual C++运行库缺失困扰,一键完成全版本部署
  • 安达发|当艺术遇见算法:APS系统如何解开工艺品行业的生产魔方
  • Obsidian Style Settings插件使用指南:打造个性化笔记界面
  • Swagger2Word终极指南:一键将API文档转为专业Word格式
  • 【C2000中断Debug】如何定位与调试异常中断
  • vue3中computed计算属性和方法的区别
  • LobeChat国际社区动态:全球开发者共同维护
  • 基于STM32的水质检测系统设计与实现
  • Radm1n1ster CN
  • 重构智慧书-第18条:实力与实干
  • 读捍卫隐私08智能出行
  • 媒体专访实录:LobeChat创始人谈开源初心
  • 小喵播放器 1.1.2| 一款支持视频超分的播放器,支持网页视频以及B站番剧
  • LobeChat待办事项提取与提醒功能实现
  • LobeChat会话管理机制揭秘:让每一次对话都井然有序
  • JS利用分片技术实现大文件分块上传的性能优化?
  • HTML5配合AES加密实现大文件分块传输安全?
  • NPP 热带森林:墨西哥查梅拉,1982-1995 年,R1
  • WordPress粘贴微信公众号内容自动排版
  • 毕设 stm32与深度学习口罩佩戴检测系统(源码+硬件+论文)
  • 手机端AIDE安卓音乐播放器软件代码
  • 如何在 Windows 11/10 中启用IE浏览器?恢复 Internet Explorer 一键搞定,就这么简单!
  • Scholar Inbox 订阅最新学术进展至邮箱
  • D.二分查找-二分答案-求最小——1283. 使结果不超过阈值的最小除数
  • A.每日一题——3562. 折扣价交易股票的最大利润