Redis Geo操作地理位置

news/2025/3/14 1:16:44/

Redis Geo

  • 使用场景
  • API列表名词
  • API列表
  • Springboot使用
    • maven
    • yaml
    • Test
  • 注意事项

Redis Geo 是Redis在3.2版本中新增的功能,用于存储和操作地理位置信息

使用场景

  1. 滴滴打车:这是一个对地理位置精度要求较高的场景。通过使用Redis的GEO功能,滴滴打车可以存储房源和店铺的地理位置信息,并根据用户所在位置的经纬度,加上范围,查询到附近的房源和店铺列表,放到高德地图中展现出来。
  2. 直播业务:比如主播开播的时候写入主播Id的经纬度,关播的时候删除主播Id元素,这样就维护了一个具有位置信息的在线主播集合提供给线上检索。
  3. 自如、蛋壳、链家、美团等平台也有根据距离找房源或者商铺的功能,这个功能也是使用的Redis的GEO功能。

API列表名词

字段含义
longitude经度
latitude纬度
member位置名称
radius距离中心位置的距离
m/km/ft/mi距离中心位置的单位,米/千米/英里/英尺
WITHCOORD返回距离中心位置元素及经纬度
WITHDIST返回距离中心位置元素及距离
WITHHASH返回距离中心位置元素及geohash 值
COUNT返回距离中心位置元素的元素个数
ASC/DESC距离远近排序
STORE key返回的集合元素存储到某个key中
STOREDIST key返回的元素距离集合存储到某个key中
BYRADIUS按圆形扫描
BYBOX按矩形扫描

API列表

名称含义指令
GEOADD用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中GEOADD key longitude latitude member [longitude latitude member …]
GEOPOS用于从给定的 key 里返回所有指定名称(member)的位置(经度和纬度)GEOPOS key member [member …]
GEOHASH用于获取一个或多个位置元素的 geohash 值GEOHASH key member [member …]
GEODIST用于返回两个给定位置之间的距离GEODIST key member1 member2 [m/km/ft/mi]
GEORADIUS以给定的经纬度为中心, 返回键包含的位置元素中, 与中心的距离不超过给定最大距离(radius)的所有位置元素GEORADIUS key longitude latitude radius [m/km/ft/mi] [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC
GEORADIUSBYMEMBER与GEORADIUS 相似,只是该指令是以位置(member)为中心GEORADIUSBYMEMBER key member radius [m/km/ft/mi] [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC/DESC] [STORE key] [STOREDIST key]
GEOSEARCH存在高版本Redis中,GEORADIUS升级,除了可以设置扫描范围,还可以设置扫描形状(圆形,矩形),geosearch的功能更加强大和灵活,可以满足更多的使用场景和需求GEOSEARCH key <member / longitude latitude> <[BYRADIUS radius [m/km/ft/mi] ]/ [BYBOX width height [m/km/ft/mi]]> [ASC/DESC] [COUNT count] [WITHCOORD] [WITHDIST][WITHHASH]

Springboot使用

maven

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency>

yaml

spring:redis:host: 127.0.0.1 # Redis 服务器地址port: 6379 # Redis 服务器端口database: 0 # Redis 数据库索引(默认为0)

Test

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.domain.geo.Metrics;
import org.springframework.test.context.junit4.SpringRunner;import java.util.List;@RunWith(SpringRunner.class)
@SpringBootTest
public class MyDemoApplicationTests {@AutowiredStringRedisTemplate redisTemplate;/*** 将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。*/@Testpublic void redisTestAdd() {Long a = redisTemplate.opsForGeo().add("geo", new Point(13.261391222476959, 38.215556214674542), "a");//params: key, Point(经度, 纬度), 地方名称Long b = redisTemplate.opsForGeo().add("geo", new Point(15.087267458438873, 37.50266842333162), "b");//params: key, Point(经度, 纬度), 地方名称System.out.println(a);System.out.println(b);}/*** 从key里返回所有给定位置元素的位置(经度和纬度)。*/@Testpublic void redisTestGeoGet() {List<Point> points = redisTemplate.opsForGeo().position("geo", "a", "b");//params: key, 地方名称...System.out.println(points);}/*** 返回两个给定位置之间的距离。*/@Testpublic void testDist() {Distance distance = redisTemplate.opsForGeo().distance("geo", "a", "b", RedisGeoCommands.DistanceUnit.KILOMETERS);//params: key, 地方名称1, 地方名称2, 距离单位System.out.println(distance);}/*** 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素,并给出所有位置元素与中心的平均距离。*/@Testpublic void redisTestNearByXY() {Circle circle = new Circle(new Point(114.05, 22.55), new Distance(200, Metrics.KILOMETERS));//Point(经度, 纬度) Distance(距离量, 距离单位)RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(5);GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisTemplate.opsForGeo().radius("geo", circle, args);//params: key, Circle, GeoRadiusCommandArgsSystem.out.println(results);}/*** 以给定的城市为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素,并给出所有位置元素与中心的平均距离。*/@Testpublic void testNearByPlace() {Distance distance = new Distance(200, Metrics.KILOMETERS);//params: 距离量, 距离单位RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(5);GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisTemplate.opsForGeo().radius("geo", "a", distance, args);//params: key, 地方名称, Circle, GeoRadiusCommandArgsSystem.out.println(results);}/*** 返回一个或多个位置元素的 Geohash 表示*/@Testpublic void testGeoHash() {List<String> results = redisTemplate.opsForGeo().hash("geo", "a", "b");//params: key, 地方名称...System.out.println(results);}}

注意事项

  • 在Redis的集群环境中,不建议将大量的数据存储在一个zset集合中,因为这会导致集群迁移时出现卡顿现象,影响线上服务的正常运行。如果数据量过大,需要对数据进行拆分,按国家、省份、城市等拆分。
  • 建议将频繁访问的数据存储在Redis中,而将低频数据存储在其他数据库中。
  • 避免将不相关的数据业务都放到一个Redis中,这可以避免业务相互影响,避免单实例膨胀,并能在故障时降低影响面,快速恢复。
  • 由于Redis是单线程服务,消息过大会阻塞并拖慢其他操作。因此,需要保持消息内容在1KB以下,严禁超过50KB的单条记录。

http://www.ppmy.cn/news/1263237.html

相关文章

C/C++指针操作整理

C/C指针操作整理 面向曾经学习过指针的人&#xff0c;并非针对究极初学者。 一维指针 数据类型存储的地址&#xff0c;指向数据存储的地址&#xff0c;可以使用 &运算符取变量的地址&#xff0c;将其赋给指针变量。 int a 2; int *p &a;同时因为C/C中数组是连续存储…

举例C#使用特性排除某些类成员不参与XML序列化和反序列化

在C#中&#xff0c;可以使用 [XmlIgnore] 特性来排除某些类成员不参与XML序列化和反序列化。这个特性告诉XML序列化器忽略被标记的成员。 以下是一个使用 [XmlIgnore] 特性的示例&#xff1a; using System; using System.IO; using System.Xml.Serialization;public class P…

Ubuntu编译文件安装SNMP服务

net-snmp源码下载 http://www.net-snmp.org/download.html 编译步骤 指定参数编译 ./configure --prefix/root/snmpd --with-default-snmp-version"2" --with-logfile"/var/log/snmpd.log" --with-persistent-directory"/var/net-snmp" --wi…

基于OpenCV的人脸识别系统案例

基于OpenCV的人脸识别系统案例 人脸识别简介代码实现案例应用情况 下面将介绍如何使用Python和OpenCV库构建一个简单但强大的人脸识别系统。人脸识别是计算机视觉领域的一个重要应用&#xff0c;具有广泛的实际用途&#xff0c;从安全门禁到娱乐应用。 人脸识别简介 人脸识别是…

GPT-Crawler一键爬虫构建GPTs知识库

GPT-Crawler一键爬虫构建GPTs知识库 写在最前面安装node.js安装GPT-Crawler启动爬虫结合 OpenAI自定义 assistant自定义 GPTs&#xff08;笔者用的这个&#xff09; 总结 写在最前面 GPT-Crawler一键爬虫构建GPTs知识库 能够爬取网站数据&#xff0c;构建GPTs的知识库&#xf…

HarmonyOS开发(九):数据管理

1、概述 1.1、功能简介 数据管理为开发者提供数据存储、数据管理能力。 它分为两个部分&#xff1a; 数据存储&#xff1a;提供通用数据持久化能力&#xff0c;根据数据特点&#xff0c;分为用户首选项、键值型数据库和关系型数据库。数据管理&#xff1a;提供高效的数据管…

四、STM32时钟系统RCC——使用HSE/HSI配置时钟

1. STM32 时钟系统介绍 1.1 STM32 时钟来源 时钟系统相当于 CPU 的脉搏&#xff0c;只有时钟起效了&#xff0c;CPU 才可以跑起来。所有时钟对于 CPU 也是至关重要的。但 STM32 的时钟系统是比较复杂的&#xff0c;51单片机只有一个系统时钟&#xff0c;而 STM32 却有多个时钟…

使用python脚本一个简单的搭建ansible集群

1.环境说明&#xff1a; 角色主机名ip地址控制主机server192.168.174.150受控主机/被管节点client1192.168.174.151受控主机/被管节点client2192.168.174.152 2.安装python和pip包 yum install -y epel-release yum install -y python python-pip 3.pip安装依赖库 pip in…