Redis--Geo指令的语法和使用场景举例(附近的人功能)
文章目录
- 前言
- Geo介绍
- Geo指令使用
- 使用场景:附近的人
- 参考文献
前言
- Redis除了常见的五种数据类型之外,其实还有一些少见的数据结构,如Geo,HyperLogLog等。虽然它们少见,但是作用却不容小觑。本文将介绍Geo指令的语法和使用场景。
Geo介绍
- Geo是"geolocation"的缩写,即地理定位器,顾名思义就是记录地理位置信息,用来进行地址位置排序的数据结构。所以它场景的应用场景便是寻找附近的人,最佳路线推荐等等。
- 说到地址位置排序,不得不提地理位置距离排序算法GeoHash算法,Redis也使用了这个算法。简单来说,这个算法就是将某地点的经度和纬度进行编码之后,成为的一维整数,整数越接近,两个地点也就越接近。通过整数可以还原出经纬度坐标,整数越长,还原出来的坐标损失程度就越小。GeoHash算法会继续对这个整数做一次base32编码,使其变成字符串。
- 于是在使用Geo数据结构时,可以简单地理解为,它只是一个zset,score是元素地址经过GeoHash算法得到的52位整数(在Redis里面,经纬度使用52位的整数进行编码),value存放该元素。
Geo指令使用
-
向Geo中添加地理空间信息:geoadd key 经度 纬度 具体元素
geoadd restaurant 95 20 "沙县小吃" geoadd restaurant 96 19 "肯德基" 120 27 "麦当劳" -
返回指定两个元素的距离:geodist key 元素1 元素2 距离单位
geodist restaurant "沙县小吃" "肯德基" km -
获取元素坐标:geopos key 元素1 … 元素n
geopos restaurant "麦当劳" geopos restaurant "沙县小吃" "肯德基" -
获取指定元素坐标的hash字符串:geohash key 元素1
geohash restaurant "沙县小吃"获取到的hash值可以到 http://geohash.org/${hash} 上进行定位,得到经纬度坐标

-
指定圆心半径,找到该圆范围内的所有元素,并按与圆心距离排序后返回:georadius key 经度 纬度 半径 单位 withdist/withcoord/withhash count n des/asc
georadius restaurant 95 21 100 km withdist count 3 asc # 查找经度95 纬度21的地点半径100公里以内的餐馆,正序输出三个餐馆withdist: 同时返回该元素与圆心的距离,距离单位为georadius指令指定的单位
withhash: 同时返回52位整数编码后的字符串
withcoord: 同时返回该元素的经纬度坐标
使用场景:附近的人
-
需求:实现查看附近的人功能。
-
实现方案:使用geo数据结构,将用户的位置经纬度保存在geo中,然后对这些信息进行查询。
-
代码实现:代码中saveUserLocation()方法负责添加用户位置信息,在添加时使用outOfChina()方法判断做位置检验,是否用户位置在国内,不在国内就不保存了,deleteUserLocation()方法负责删除某用户的位置信息,getNearByLocation()方法负责查询某个地方附近的用户。
public class NearbyPeopleDemo {public static void main(String[] args) {Jedis jedis = new Jedis("127.0.0.1");jedis.del(LOCATION_KEY);double lon ;double lat ;//向redis中存放用户的地址,随机生成一万个用户。for(int i = 0;i<10000;i++){lon = Math.random()*(138-72+1)+72;lat = Math.random()*(55-0+1);//判断该位置是否属于中国,不属于就不加了if(!outOfChina(lon,lat)) {saveUserLocation("用户"+i, lon, lat, jedis);}}System.out.println("添加用户位置信息完毕!");System.out.println("距离经度100,纬度35位置100km以内的人有哪些:"+getNearByLocation(100, 35, 100, jedis));}private static final String LOCATION_KEY = "location";/*** 保存用户位置信息* @param userId 用户id* @param longitude 经度* @param latitude 纬度* @param jedis*/public static void saveUserLocation(String userId, double longitude, double latitude, Jedis jedis){jedis.geoadd(LOCATION_KEY,longitude,latitude,userId);}/*** 根据用户id删除用户位置信息,采用zset的删除方式删除即可* @param userId* @param jedis*/public static void deleteUserLocation(String userId,Jedis jedis){jedis.zrem(LOCATION_KEY,userId);}/*** 查询附近的人* @param longitude 经度* @param latitude 纬度* @param radius 半径* @param jedis* @return*/public static List<String> getNearByLocation(double longitude, double latitude,double radius,Jedis jedis){List<GeoRadiusResponse> georadius = jedis.georadius(LOCATION_KEY, longitude, latitude, radius, GeoUnit.KM);return georadius.stream().map(GeoRadiusResponse::getMemberByString).collect(Collectors.toList());}/*** 判断经纬度是否超过了中国* @param longitude 经度* @param latitude 纬度* @return*/public static boolean outOfChina(double longitude,double latitude){if (longitude < 72.004 || longitude > 137.8347)return true;if (latitude < 0.8293 || latitude > 55.8271)return true;return false;}} -
测试结果:我们在main方法中,随机生成一万个用户位置信息,保存在redis中,之后调用getNearByLocation()方法查找距离经度100,纬度35的位置100km以内的人有哪些,运行结果如下:

参考文献
- 《91.Redis深度历险 核心原理与应用实践》–钱文品
相关文章:
Redis--Geo指令的语法和使用场景举例(附近的人功能)
文章目录 前言Geo介绍Geo指令使用使用场景:附近的人参考文献 前言 Redis除了常见的五种数据类型之外,其实还有一些少见的数据结构,如Geo,HyperLogLog等。虽然它们少见,但是作用却不容小觑。本文将介绍Geo指令的语法和…...
127.0.0.1和0.0.0.0的区别
在网络开发中,经常会涉及到两个特殊的IP地址:127.0.0.1和0.0.0.0。这两者之间有一些关键的区别,本文将深入介绍它们的作用和用途。 127.0.0.1 127.0.0.1 是本地回环地址,通常称为 “localhost”。作用是让网络应用程序能够与本地…...
SpringBoot ES 聚合后多字段加减乘除
SpringBoot ES 聚合后多字段加减乘除 在SpringData Elasticsearch中,聚合统计的原理主要依赖于Elasticsearch本身的聚合框架。Elasticsearch提供了强大的聚合功能,使得你可以对文档进行各种计算和统计,从而得到有关数据集的有用信息。 Elast…...
React16源码: React中requestCurrentTime和expirationTime的源码实现补充
requestCurrentTime 1 )概述 关于 currentTime,在计算 expirationTime 和其他的一些地方都会用到 从它的名义上来讲,应等于performance.now() 或者 Date.now() 就是指定的当前时间在react整体设计当中,它是有一些特定的用处和一些…...
【论文阅读】Deep Graph Contrastive Representation Learning
目录 0、基本信息1、研究动机2、创新点3、方法论3.1、整体框架及算法流程3.2、Corruption函数的具体实现3.2.1、删除边(RE)3.2.2、特征掩盖(MF) 3.3、[编码器](https://blog.csdn.net/qq_44426403/article/details/135443921)的设…...
设计模式-简单工厂
设计模式-简单工厂 简单工厂模式是一个集中管理对象创建,并根据条件生成所需类型对象的设计模式,有助于提高代码的复用性和维护性,但可能会导致工厂类过于复杂且违反开闭原则。 抽象提取理论: 封装对象创建过程解耦客户端与产品…...
Django ORM 中的单表查询 API(1)
在 Django 中,对象关系映射(ORM)提供了一种功能强大、表现力丰富的数据库交互方式。ORM 允许开发人员使用高级 Python 代码执行数据库查询,从而更轻松地处理数据库实体。 下面,我们将探讨 Django ORM 中单表查询 API …...
电子雨html代码
废话不多说下面是代码: <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><title>Code</title><style>body{margin: 0;overflow: hidden;}</style></head><body><c…...
xadmin基于Django的后台管理系统安装与使用
xadmin是基于Django的后台管理系统 官网:http://sshwsfc.github.io/xadmin/ github地址:https://github.com/sshwsfc/xadmin 安装方式 pip安装 pip install xadmin在setting配置中添加: INSTALLED_APPS [xadmin,crispy_forms, ]在urls.py…...
[go语言]输入输出
目录 知识结构 输入 1.Scan 编辑 2.Scanf 3.Scanln 4.os.Stdin --标准输入,从键盘输入 输出 1.Print 2.Printf 3.Println 知识结构 输入 为了展示集中输入的区别,将直接进行代码演示。 三者区别的结论:Scanf格式化输入&#x…...
【SpringBoot系列】AOP详解
🤵♂️ 个人主页:@香菜的个人主页,加 ischongxin ,备注csdn ✍🏻作者简介:csdn 认证博客专家,游戏开发领域优质创作者,华为云享专家,2021年度华为云年度十佳博主 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收…...
openssl3.2 - 官方demo学习 - signature - rsa_pss_hash.c
文章目录 openssl3.2 - 官方demo学习 - signature - rsa_pss_hash.c概述笔记END openssl3.2 - 官方demo学习 - signature - rsa_pss_hash.c 概述 对私钥对明文做签名(摘要算法为SHA256) 用公钥对密文做验签(摘要算法为SHA256) 笔记 /*! \file rsa_pss_hash.c \note openss…...
Redis相关知识点
1.什么是Redis Redis (REmote DIctionary Server) 是用 C 语言开发的一个开源的高性能键值对(key-value)数据库,它支持网络,可基于内存亦可持久化,并提供多种语言的API。Redis具有高效性、原子性、支持多种数据结构、…...
嵌入式开发--STM32G4系列片上FLASH的读写
这个玩意吧,说起来很简单,就是几行代码的事,但楞是折腾了我大半天时间才搞定。原因后面说,先看代码吧: 读操作 读操作很简单,以32位方式读取的时候是这样的: data *(__IO uint32_t *)(0x080…...
嵌入式-Stm32-江科大基于标准库的GPIO的八种模式
文章目录 一:GPIO输入输出原理二:GPIO基本结构三:GPIO位结构四:GPIO的八种模式道友:相信别人,更要一百倍地相信自己。 (推荐先看文章:《 嵌入式-32单片机-GPIO推挽输出和开漏输出》…...
2024年1月17日Arxiv热门NLP大模型论文:THE FAISS LIBRARY
Meta革新搜索技术!提出Faiss库引领向量数据库性能飞跃 引言:向量数据库的兴起与发展 随着人工智能应用的迅速增长,需要存储和索引的嵌入向量(embeddings)数量也在急剧增加。嵌入向量是由神经网络生成的向量表示&…...
深度解析JVM类加载器与双亲委派模型
概述 Java虚拟机(JVM)是Java程序运行的核心,其中类加载器和双亲委派模型是JVM的重要组成部分。本文将深入讨论这两个概念,并解释它们在实际开发中的应用。 1. 什么是类加载器? 类加载器是JVM的一部分,负…...
前端下载文件流,设置返回值类型responseType:‘blob‘无效的问题
前言: 本是一个非常简单的请求,即是下载文件。通常的做法如下: 1.前端通过Vue Axios向后端请求,同时在请求中设置响应体为Blob格式。 2.后端相应前端的请求,同时返回Blob格式的文件给到前端(如果没有步骤…...
C++核心编程——类和对象(一)
本专栏记录C学习过程包括C基础以及数据结构和算法,其中第一部分计划时间一个月,主要跟着黑马视频教程,学习路线如下,不定时更新,欢迎关注。 当前章节处于: ---------第1阶段-C基础入门 ---------第2阶段实战…...
脱模斜度是什么意思,为什么要有脱模斜度,没有斜度不行吗?
问题描述:脱模斜度是什么意思,为什么要有脱模斜度,没有斜度不行吗? 问题解答: 脱模斜度是指在模具中的零件在脱模(从模具中取出)过程中相对于模具开合方向的倾斜程度。在模具设计和制造中&…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
