Redis那些事儿(三)

文章目录

    • 1. 前言
    • 2. 常用api介绍
    • 3. 需求假设(获取离我最近的停车场)
    • 4. 代码示例

1. 前言

        接着上一篇Redis那些事儿(二) ,这一篇主要介绍Redis基于Geo数据结构实现的地理服务,它提供了一种方便的方式来存储和处理与地理位置相关的数据。Geo数据结构是Redis的一种特殊数据类型,用于存储地理位置信息,每个地理位置被表示为经度和纬度的坐标,可以将这些坐标与一个或多个成员关联起来。Redis的地理服务提供了一套简单而强大的功能,可以方便地存储和处理与地理位置相关的数据,它适用于许多应用场景,如地理定位、附近的人、附近的店铺搜索、附近的停车场、附近的地铁站…等等,大大提升了定位排序的效率。

2. 常用api介绍

        Redis地理服务API方法包括:GEOADD(向Geo数据结构中添加一个或多个地理位置信息);GEODIST(计算两个地理位置之间的距离);GEORADIUS(获取给定地理位置附近一定范围内的成员);GEOPOS(获取给定成员的经纬度坐标);GEOHASH(获取给定成员的Geohash值)…以上都是Geo地理服务内置的常用方法,接下来还是基于开发中的StringRedisTemplate对象作为切入点,更直观地说明实际应用中对于Geo地理服务地应用。
        StringRedisTemplate中定义了RedisGeoCommands的接口,RedisGeoCommands中封装了一系列的内置方法及子类,所以Redis中基于opsForGeo()的操作都离不开RedisGeoCommands,如下为部分截图:
RedisGeoCommands部分截图

Geo数据结构中存入坐标数据,redisTemplate.opsForGeo().add(key, locations)

		List<Park> parks = getParks(); //TODO 获取停车场列表信息//初始化Redis区域对象集合List<RedisGeoCommands.GeoLocation<String>> locations = new ArrayList<>();for (Park park : parks) {//实例化ponit对象,传参[经度、纬度]Point point = new Point(park.getLng(), park.getLat());//构造location对象,传参[name值(一般取ID)、point对象]RedisGeoCommands.GeoLocation<String> location = new RedisGeoCommands.GeoLocation<>(park.getParkId() + "", point);locations.add(location);}String key = "GEO_PARK_KEY";//存入坐标数据redisTemplate.opsForGeo().add(key, locations);

Geo数据结构中删除坐标数据,redisTemplate.opsForGeo().remove(key, …members)

		String key = "GEO_PARK_KEY";//删除单个坐标数据(parkId为单个停车场ID,类型为String)redisTemplate.opsForGeo().remove(key, parkId);//删除多个坐标数据(第一个参数为key,后面可以传入多个parkId)redisTemplate.opsForGeo().remove(key, parkId1, parkId2, parkId3);

Geo数据结构中检索坐标数据由近到远,redisTemplate.opsForGeo().radius(key, within, args)

		String key = "GEO_PARK_KEY";//检索20公里内的Distance distance = new Distance(20, Metrics.KILOMETERS);//以目标坐标为圆心,distance为半径的圆圈范围,其中lng代表中心坐标的经度、lat代表中心坐标的纬度Circle within = new Circle(new Point(lng, lat), distance);//条件参数,按照距离查询,默认就是升序RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance();//执行查询GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisTemplate.opsForGeo().radius(key, within, args);

Geo数据结构中检索坐标数据由近到远,redisTemplate.opsForGeo().search(key, reference, distance, args)

		String key = "GEO_PARK_KEY";//检索20公里内的Distance distance = new Distance(20, Metrics.KILOMETERS);//条件参数,按照距离查询,默认就是升序RedisGeoCommands.GeoSearchCommandArgs args = RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance();//中心点位确认,其中lng代表中心坐标的经度、lat代表中心坐标的纬度GeoReference<String> reference = GeoReference.fromCoordinate(lng, lat);//执行查询GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisTemplate.opsForGeo().search(key, reference, distance, args);

        以上列了四个最常用的方式,类似于我们最常规的CURD,其中最后两个radius和search是查询方法,二者最终查询的结果是一致的,只是手段方式不同而已!

3. 需求假设(获取离我最近的停车场)

        这个时候有人就说了:我使用GeodeticCalculator工具类在代码中计算距离也很方便的啊。我想了想,确实很方便,只需要引入geodesy的依赖,就可以直接使用GeodeticCalculator的calculateGeodeticCurve方法就可以计算了,还不需要麻烦的用redis搞那么长的代码了。但是,问题来了,就以停车场为例,假如只有十几个停车场,遍历一下然后按升序排个序,很快就计算出了离我最近的停车场列表了。如果我有上千个或者上万个停车场,总不能遍历上万次然后再排序吧,那这速度就一言难尽了…如果这个时候使用redis的geo数据结构来读取,那就完美解决这个问题了。Redis提供的GeoHash算法功能对于这方面的需求就太好用了,那么,附近的停车场、附近的人、附近的商家就都是一个思路了!

4. 代码示例

	/*** 获取距离最近的停车场列表,由近到远* @param lng 当前位置经度* @param lat 当前位置纬度* @param page 页数(第n页)* @param size 每页数量(10、20...)* @param value 公里范围内(搜索范围半径)* @return*/public List<Park> getLatestParks(Double lng, Double lat, Integer page, Integer size, Double value){//计算分页起始参数Integer start = (page - 1) * size;Integer end = page * size;//查询redis,按照距离排序String key = "GEO_PARK_KEY";//检索value公里内的Distance distance = new Distance(value, Metrics.KILOMETERS);//以目标坐标为圆心,distance为半径的圆圈范围,其中lng代表中心坐标的经度、lat代表中心坐标的纬度Circle within = new Circle(new Point(lng, lat), distance);//条件参数,按照距离查询,默认就是升序,截止到endRedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().limit(end);//执行查询GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisTemplate.opsForGeo().radius(key, within, args);if (results == null) {return new ArrayList<>();}//获取最终检索的内容List<GeoResult<RedisGeoCommands.GeoLocation<String>>> content = results.getContent();//截取从起始到结束,如果总数小于起始数就证明已经页数超了,返回空集合if (content.size() <= start) {return new ArrayList<>();}//初始化parkId集合List<Long> parkIds = new ArrayList<>();//初始化距离mapMap<String, Distance> distanceMap = new HashMap<>();//分页跳过之前的数据,并遍历赋值content.stream().skip(start).forEach(i->{String parkIdStr = i.getContent().getName();parkIds.add(Long.valueOf(parkIdStr));Distance dis = i.getDistance();distanceMap.put(parkIdStr, dis);});//固定排序String join = StringUtils.join(parkIds,",");//根据parkId集合获取park集合List<Park> newParks = parkService.list(new QueryWrapper<Park>().in("park_id", parkIds).last("ORDER BY FIELD(park_id," + join + ")")).stream().map(i -> {i.setDistance(distanceMap.get(i.getParkId() + "").getValue());return i;}).collect(Collectors.toList());return newParks;}

以上代码为由近到远获取距离最近的停车场列表的示例方法,仅供参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/131790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

库房管理软件采购申请流程代码实现解析

300rmb掏了个javavue2的小系统&#xff0c;学习代码&#xff0c;调整下申请流程。 原有的入库流程是&#xff0c;库管&#xff08;admin&#xff09;提出采购申请给采购员&#xff08;caigou&#xff09;&#xff0c;采购员采购入库时点击入库完成采购入库流程。 想弄清后端代…

非关系型数据库Redis的安装【Linux】及常用命令

前言 Redis&#xff08;Remote Dictionary Server&#xff09;是一种开源的内存数据库管理系统&#xff0c;它以键值存储方式来存储数据&#xff0c;并且支持多种数据结构&#xff0c;如字符串、哈希、列表、集合、有序集合等。Redis最初由Salvatore Sanfilippo开发&#xff0c…

数据分析实战 | 关联规则分析——购物车分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据预处理 七、生成频繁项集 八、计算关联度 九、可视化 一、数据及分析对象 数据集链接&#xff1a;Online Retail.xlsx 该数据集记录了2010年12月01日至2011年12月09日…

性能优于BERT的FLAIR:一篇文章入门Flair模型

文章目录 What is FLAIR&#xff1f;FLAIR ModelContextual String Embedding for Sequence Labelingexample FLAIR Application AreaSentiment AnalysisNamed Entity RecognitionText Classification FLAIR一、什么是FLAIR&#xff1f;二、FLAIR Library的优势是什么&#xff…

突破性技术!开源多模态模型—MiniGPT-5

多模态生成一直是OpenAI、微软、百度等科技巨头的重要研究领域&#xff0c;但如何实现连贯的文本和相关图像是一个棘手的难题。 为了突破技术瓶颈&#xff0c;加州大学圣克鲁斯分校研发了MiniGPT-5模型&#xff0c;并提出了全新技术概念“Generative Vokens "&#xff0c…

❤️ React的安装和使用(实战篇)

React的安装和使用 一、React的安装和使用 reactJs警告提示&#xff1a; This version of tar is no longer supported, and will not receive security updates. Please upgrade asap 翻译&#xff1a;tar2.2.2&#xff1a;此版本的tar不再受支持&#xff0c;将不会收到安全…

golang实现极简todolist

ToDoList 最近跟着qimi老师做了一个ToDoList&#xff0c;我做的GitHub地址贴在这里&#xff0c;但由于前端出了点问题&#xff0c;所以都是用postman进行测试 原项目地址 部分功能展示 删除代办 查找代办 下面给出思路 思路 其实这是一个很简单的增删改查的实现&#xff…

linux下使用vscode对C++项目进行编译

项目的目录结构 头文件swap.h 在自定义的头文件中写函数的声明。 // 函数的声明 void swap(int a,int b);swap.cpp 导入函数的声明&#xff0c;写函数的定义 #include "swap.h" // 双引号表示自定义的头文件 #include <iostream> using namespace std;// 函…

LeetCode.6 N字形变换

一开始想的是真的创建一个数组 去按照题目所给的要求填入数据 最后输出不为空的数组项 但是不仅时间复杂度高 而且错误频繁出现 最终也没有提交成功 查阅题解后发现数组并不重要 假设我们忽略掉数组中的那些空白项 最终输出的结果就是numRows行的字符串的拼接 string conver…

apachesolr中简单使用

core使用 首先点击add core 可以看到报错solrconfig.xml不在new_core目录下&#xff0c;new_core是我们点击后自动创建的 那么我们将D:\solr2\solr-9.3.0\solr-9.3.0\server\solr\configsets下的任何一个目录下的conf拷贝到new_core过去 这里是使用_default下的conf目录拷贝…

【PC电脑windows环境下-[jetson-orin-NX]Linux环境下-下载工具esptool工具使用-相关细节-简单样例-实际操作】

【PC电脑windows环境下-[jetson-orin-NX]Linux环境下-下载工具esptool工具使用-相关细节-简单样例-实际操作】 1、概述2、实验环境3、 物品说明4-2、自我总结5、本次实验说明1、准备样例2、设置芯片3、编译4、下载5、验证 &#xff08;1&#xff09;windows环境下进行烧写1、下…

RabbitMQ 消息应答与发布

目录 一、消息应答 1、自动应答&#xff08;默认&#xff09; 2、手动消息应答的方法 ​编辑 3、消息重新入队 4、手动应答案列与效果演示 二、RabbitMQ持久化 1、队列持久化 2、消息持久化 三、不公平分发&#xff08;能者多劳&#xff0c;弱者少劳&#xff09; 1、…

算法通过村第十八关-回溯|青铜笔记|什么叫回溯(中篇)

文章目录 前言回溯的核心问题撤销操作解释总结 前言 提示&#xff1a;阳光好的时候&#xff0c;会感觉还可以活很久&#xff0c;甚至可以活出喜悦。 --余秀华 回溯是非常重要的算法思想之一&#xff0c;主要解决一些暴力枚举也搞不定的问题&#xff08;这里埋个坑&#x1f4a3;…

NTFS文件系统解析(三)

1、引言 对于NTFS文件系统而言&#xff0c;无论文件内容本身&#xff0c;抑或真实的文件属性&#xff0c;都被称之为属性。 而正如前文说到的&#xff0c;NTFS预定义了16种属性用于文件系统的管理。 而通常情况下&#xff0c;往往只需要关注其中的某些属性即可。 2、属性头 …

云智慧联合北航提出智能运维(AIOps)大语言模型及评测基准

随着各行业数字化转型需求的不断提高&#xff0c;人工智能、云计算、大数据等新技术的应用已不仅仅是一个趋势。各行业企业和组织纷纷投入大量资源&#xff0c;以满足日益挑剔的市场需求&#xff0c;追求可持续性和竞争力&#xff0c;这也让运维行业迎来了前所未有的挑战和机遇…

数据结构-二叉树·堆(顺序结构的实现)

&#x1f389;个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名乐于分享在学习道路上收获的大二在校生 &#x1f43b;‍❄个人主页&#x1f389;&#xff1a;GOTXX &#x1f43c;个人WeChat&#xff1a;ILXOXVJE&#x1f43c;本文由GOTXX原创&#xff0c;首发CSDN&…

【wp】2023鹏城杯初赛 Web web1(反序列化漏洞)

考点&#xff1a; 常规的PHP反序列化漏洞双写绕过waf 签到题 源码&#xff1a; <?php show_source(__FILE__); error_reporting(0); class Hacker{private $exp;private $cmd;public function __toString(){call_user_func(system, "cat /flag");} }class A {p…

Ansible中的角色使用

Ansible中的角色使用&#xff1a; 目录 一、ansible角色简介 二、roles目录结构 三、roles的创建 四、roles的使用 1、书写task主任务 2、触发器模块 3、变量模块 4、j2模块 5、files模块 6、启用模块 7、执行playbook 五、控制任务执行顺序 六、多重角色的使用 一…

数据结构(超详细讲解!!)第二十一节 特殊矩阵的压缩存储

1.压缩存储的目标 值相同的元素只存储一次 压缩掉对零元的存储&#xff0c;只存储非零元 特殊形状矩阵&#xff1a; 是指非零元&#xff08;如值相同的元素&#xff09;或零元素分布具有一定规律性的矩阵。 如&#xff1a; 对称矩阵 上三角矩阵 下三角矩阵 对角矩阵 准…

redis教程 二 redis客户端Jedis使用

文章目录 Redis的Java客户端-JedisJedis快速入门创建工程&#xff1a;引入依赖&#xff1a;建立连接测试&#xff1a;释放资源Jedis连接池创建Jedis的连接池改造原始代码 Redis的Java客户端-SpringDataRedis快速入门导入pom坐标配置文件测试代码 数据序列化器StringRedisTempla…