胖胖的枫叶
主页
博客
产品设计
企业架构
全栈开发
效率工具
数据分析
项目管理
方法论
面试
  • openJdk-docs
  • spring-projects-docs
  • mysql-docs
  • redis-commands
  • redis-projects
  • apache-rocketmq
  • docker-docs
  • mybatis-docs
  • netty-docs
  • journaldev
  • geeksforgeeks
  • 后端进阶
  • 并发编程网
  • 英语肌肉记忆锻炼软件
  • 墨菲安全
  • Redisson-docs
  • jmh-Visual
  • 美团技术
  • MavenSearch
主页
博客
产品设计
企业架构
全栈开发
效率工具
数据分析
项目管理
方法论
面试
  • openJdk-docs
  • spring-projects-docs
  • mysql-docs
  • redis-commands
  • redis-projects
  • apache-rocketmq
  • docker-docs
  • mybatis-docs
  • netty-docs
  • journaldev
  • geeksforgeeks
  • 后端进阶
  • 并发编程网
  • 英语肌肉记忆锻炼软件
  • 墨菲安全
  • Redisson-docs
  • jmh-Visual
  • 美团技术
  • MavenSearch
  • 标签索引
  • 2024年

    • 配置Mac环境
    • 业务知识会计管理
    • 业务知识会计基础
    • 业务知识什么是财务
  • 2023年

    • 项目 Boi
  • 2022年

    • 企业架构故障管理
    • 企业架构开发债务
  • 2021年

    • Python3.8 Matplotlib员工数据分析
    • Python3.8 Matplotlib IP折线图
    • Python3.8 词云 IP地址
    • Redis RediSearch
    • Rust第一个CLI程序
    • Rust所有权
    • Rust函数与控制流
    • Rust变量与数据类型
    • Rust入门
    • 企业架构分布式系统
    • 编程式权限设计
    • Java JVM优化
    • SpringBoot MyBatis 批量
    • SpringBoot 测试Mock
    • SpringBoot Redis布隆过滤器
    • CentOS7 Jenkins 部署
    • SpringBoot WebClient
    • Docker Drone 部署
    • SpringBoot MyBatis
    • SpringBoot Redisson
    • SpringBoot MyBatis 雪花算法
    • Java Netty
    • Redis 扫描
    • CentOS7 Jenkins本地部署分级
    • Mac 安装 Neo4j Jupyter
    • Mac OpenJDK11 JavaFX 环境
    • Mac 安装 Jenv
    • SpringBoot Redis 延时队列
    • SpringBoot MDC日志
    • SpringBoot 定时任务
    • CentOS7 Nginx GoAccess
    • SpringBoot MyBatis 分析
    • SpringBoot Lucene
    • 企业架构分布式锁
    • 学习技巧减少学习排斥心理
    • SpringBoot 动态数据源
    • Docker Compose SpringBoot MySQL Redis
    • SpringBoot 阻塞队列
    • Docker Compose Redis 哨兵
    • Docker Compose Redis 主从
    • 网络通信
  • 2020年

    • SpringBoot 延时队列
    • MySQL基础(四)
    • Java 雪花算法
    • Redis Geo
    • 网络通信 Tcpdump
    • Spring SPI
    • Java Zookeeper
    • SpringBoot JMH
    • 网络通信 Wireshark
    • Docker Compose Redis MySQL
    • CentOS7 Docker 部署
    • Netty 源码环境搭建
    • MySQL基础(三)
    • CentOS7 Selenium运行环境
    • CentOS7 Nginx HTTPS
    • Java JMH
    • SpringBoot 修改Tomcat版本
    • Java Eureka 钉钉通知
    • SpringBoot 错误钉钉通知
    • Java JVM
    • Git 合并提交
    • CentOS7 OpenResty 部署
  • 2019年

    • Redis CLI
    • CentOS7 Nginx 日志
    • 编程式代码风格
    • IDEA 插件
    • Skywalking 源码环境搭建
    • SpringBoot Redis 超时错误
    • 编程式 gRPC
    • Java Arthas
    • Docker Compose Redis 缓存击穿
    • Docker ElasticSearch5.6.8 部署
    • Docker Mysql5.7 部署
    • Spring Redis 字符串
    • Docker Zookeeper 部署
    • Docker Redis 部署
    • SpringBoot Dubbo
    • CentOS7 CMake 部署
    • 应用程序性能指标
    • Java Code 递归
    • CentOS7 ELK 部署
    • CentOS7 Sonarqube 部署
    • Java Selenium
    • Java JJWT JUnit4
    • Spring 源码环境搭建
    • Java JUnit4
    • Java Web JSON Token
    • 编程式 FastDFS
    • Java XPath
    • Redis基础(二)
    • Redis基础(一)
    • Java MyBatis JUnit4
    • Java MyBatis H2 JUnit4
    • MyBatis 源码环境搭建
    • Git 配置
    • Java 核心
    • Java Dubbo
    • Java JavaCollecionsFramework
    • Java Maven
    • Java MyBatis
    • Java Spring
    • Java SpringMVC
    • MySQL
    • Redis
  • 2018年

    • Java HashMap
    • Java HashSet
    • Java Code 交换值
    • Spring Upgrade SpringBoot
    • Mac 编程环境
    • Java Log4j
    • 网络通信 Modbus
    • MySQL基础(二)
    • MySQL基础(一)
    • Java Stack
    • Java Vector
    • CentOS7 RabbitMQ 部署
    • CentOS7 Redis 部署
    • CentOS7 MongoDB 部署
    • CentOS7 基础命令
    • Java Eureka Zookeeper
    • CentOS7 MySQL 部署
    • Git 分支
    • CentOS7 Java环境配置
    • Java LinkedList
    • Java ArrayList
    • Spring Annotation Aop

Redis Geo

源码地址

Geo

Redis 在 3.2 版本中增加了 GEO 类型用于存储和查询地理位置。

  • GEOADD:添加地理位置

  • GEOPOS:查询位置信息

  • GEODIST:距离统计

  • GEORADIUS:以给定的经纬度为中心, 找出某一半径内的元素

  • GEORADIUSBYMEMBER 找出位于指定范围内的元素,中心点是由给定的位置元素决定

  • GEOHASH:返回一个或多个位置元素HASH

  • 关于删除,使用集合函数中的zrem,geo本质存在一个集合中。

演示效果

  • 使用百度地图,标记出5个坐标。百度地图坐标获取 百度地图
        // 1.杭州市 蒋村商务中心 120.075338,30.294845
        // 2.杭州市 中节能西溪首座 120.081806,30.294907
        // 3.杭州市 西溪蝶园 120.070452,30.294221
        // 4.杭州市 西溪财富中心 120.077854,30.296342
        // 5.杭州市 九橙 西溪创投中心 120.055468,30.284523
  • 使用redis-cli作为客户端测试工具 geo 集合key = hz

GEOADD

  • 添加坐标信息
127.0.0.1:6379> geoadd hz 120.075338 30.294845 1 
(integer) 1
127.0.0.1:6379> geoadd hz 120.081806 30.294907 2
(integer) 1
127.0.0.1:6379> geoadd hz 120.070452 30.294221 3
(integer) 1
127.0.0.1:6379> geoadd hz 120.077854 30.296342 4
(integer) 1
127.0.0.1:6379> geoadd hz 120.055468 30.284523 5
(integer) 1
127.0.0.1:6379> 

GEOPOS

  • 从键里面返回所有给定位置元素的位置(经度和纬度)
127.0.0.1:6379> geopos hz 1 2 
1) 1) "120.07533878087997437"
   2) "30.29484408467364176"
2) 1) "120.08180826902389526"
   2) "30.29490745270262408"

GEODIST

  • 返回两个给定位置之间的距离。如果两个位置之间的其中一个不存在, 那么命令返回空值。
  • 指定单位的参数 unit 必须是以下单位的其中一个
    • m 表示单位为米。
    • km 表示单位为千米。
    • mi 表示单位为英里。
    • ft 表示单位为英尺。
127.0.0.1:6379> geodist hz 1 2 m
"621.3522"
# 获取 1 和 2 之间的距离米
  • 拿百度地图的尺子测试下。差了6米问题不大。精度不高的业务够用了。

GEORADIUS

  • 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
  • 范围可以使用以下其中一个单位:
    • m 表示单位为米。
    • km 表示单位为千米。
    • mi 表示单位为英里。
    • ft 表示单位为英尺。
  • 在给定以下可选项时, 命令会返回额外的信息:
    • WITHDIST : 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
    • WITHCOORD : 将位置元素的经度和维度也一并返回。
    • WITHHASH : 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。
  • 默认命令的排序
    • ASC : 根据中心的位置, 按照从近到远的方式返回位置元素。
    • DESC : 根据中心的位置, 按照从远到近的方式返回位置元素。
127.0.0.1:6379> georadius hz 120.075338 30.294845 500 m 
1) "3"
2) "1"
3) "4"
# 中心坐标 120.075338 30.294845 500m内的位置。

127.0.0.1:6379> georadius hz 120.075338 30.294845 500 m WITHDIST
1) 1) "3"
   2) "474.3718"
2) 1) "1"
   2) "0.1264"
3) 1) "4"
   2) "293.5036"
# 中心坐标 120.075338 30.294845 500m内的位置,并显示距离m。

127.0.0.1:6379> georadius hz 120.075338 30.294845 500 m WITHDIST WITHCOORD ASC
1) 1) "1"
   2) "0.1264"
   3) 1) "120.07533878087997437"
      2) "30.29484408467364176"
2) 1) "4"
   2) "293.5036"
   3) 1) "120.0778546929359436"
      2) "30.29634210487881063"
3) 1) "3"
   2) "474.3718"
   3) 1) "120.07045179605484009"
      2) "30.2942205432684446"
# 中心坐标 120.075338 30.294845 500m内的位置,并显示距离,ASC排序。
  • 一般用来做附近的人(建筑等等)

GEORADIUSBYMEMBER

  • 找出位于指定范围内的元素,参数是元素而不是坐标。

  • 范围可以使用以下其中一个单位:

    • m 表示单位为米。
    • km 表示单位为千米。
    • mi 表示单位为英里。
    • ft 表示单位为英尺。
  • 在给定以下可选项时, 命令会返回额外的信息:

    • WITHDIST : 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
    • WITHCOORD : 将位置元素的经度和维度也一并返回。
    • WITHHASH : 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。
  • 默认命令的排序

    • ASC : 根据中心的位置, 按照从近到远的方式返回位置元素。
    • DESC : 根据中心的位置, 按照从远到近的方式返回位置元素。
127.0.0.1:6379> GEORADIUSBYMEMBER hz 1 500 m
1) "3"
2) "1"
3) "4"
# 元素 500m的元素

127.0.0.1:6379> GEORADIUSBYMEMBER hz 1 500 m WITHDIST WITHCOORD ASC
1) 1) "1"
   2) "0.0000"
   3) 1) "120.07533878087997437"
      2) "30.29484408467364176"
2) 1) "4"
   2) "293.4996"
   3) 1) "120.0778546929359436"
      2) "30.29634210487881063"
3) 1) "3"
   2) "474.4311"
   3) 1) "120.07045179605484009"
      2) "30.2942205432684446"
# 元素 500m的元素包含完整信息。
  • 一般用来做附近的人(建筑等等)

GEOHASH

127.0.0.1:6379> GEOHASH hz 1 2 3 
1) "wtmkk7h0q00"
2) "wtmkke0bsu0"
3) "wtmkk6bssk0"

删除坐标

  • 关于删除,使用集合函数中的zrem,geo本质存在一个集合中。
127.0.0.1:6379> GEORADIUSBYMEMBER hz 1 500 m
1) "3"
2) "1"
3) "4"
# 元素 500m的元素
127.0.0.1:6379> zrem hz 4
(integer) 1
127.0.0.1:6379> GEORADIUSBYMEMBER hz 1 500 m
1) "3"
2) "1"
# 将 4 元素删除后只能看到 3 1 了。

代码演示

  • spring boot 2.4.5
  • gson

配置项目


/**
 * @author z201.coding@gmail.com
 * @date 2021/12/24
 **/
@Configuration
public class RedisConfig {

    // 防止key 出现乱码
    @Bean
    public RedisTemplate redisTemplate(LettuceConnectionFactory connectionFactory) {
        RedisTemplate template = new RedisTemplate();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        template.setConnectionFactory(connectionFactory);
        // key序列化方式
        template.setKeySerializer(redisSerializer);
        // value序列化
        template.setValueSerializer(redisSerializer);
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(LettuceConnectionFactory connectionFactory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(connectionFactory);
        return stringRedisTemplate;
    }
}

单元测试代码

    
 package cn.z201.redis;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.RedisTemplate;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.*;


@Slf4j
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = AppApplication.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class AppApplicationTest {

    @Autowired
    RedisTemplate redisTemplate;

    @Test
    public void testGeo() {
        // 1.杭州市 蒋村商务中心 120.075338,30.294845
        // 2.杭州市 中节能西溪首座 120.081806,30.294907
        // 3.杭州市 西溪蝶园 120.070452,30.294221
        // 4.杭州市 西溪财富中心 120.077854,30.296342
        // 5.杭州市 九橙 西溪创投中心 120.055468,30.284523
        Map<String, Point> points = new HashMap<>();
        points.put("1", new Point(120.075338, 30.294845));
        points.put("2", new Point(120.081806, 30.294907));
        points.put("3", new Point(120.070452, 30.294221));
        points.put("4", new Point(120.077854, 30.296342));
        points.put("5", new Point(120.055468, 30.284523));
        Long result = redisTemplate.opsForGeo().add("site", points);
        log.info("{}", result);
        Set<String> keys = redisTemplate.keys("*");
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        log.info("size -> {} ", keys.size());
        List<Point> pointList = redisTemplate.opsForGeo().position("site", "1", "2");
        log.info("pointList -> {} ", gson.toJson(pointList));
        /**
         * 	METERS(6378137, "m"),
         * 	KILOMETERS(6378.137, "km"),
         * 	MILES(3963.191, "mi"),
         * 	FEET(20925646.325, "ft");
         */
        Distance distance = redisTemplate.opsForGeo().distance("site", "1", "2", RedisGeoCommands.DistanceUnit.KILOMETERS);
        log.info("distance -> {} ", gson.toJson(distance));
        Circle circle = new Circle(new Point(120.075338, 30.294845), new Distance(500, RedisGeoCommands.DistanceUnit.KILOMETERS));
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
                .includeDistance()
                .includeCoordinates()
                .sortAscending();
        log.info("geoLocationGeoResults -> {} ", gson.toJson(args));
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoLocationGeoResults = redisTemplate.opsForGeo().radius("site", circle, args);
        log.info("geoLocationGeoResults -> {} ", gson.toJson(geoLocationGeoResults));
        keys.forEach(item -> {
                    if (!Objects.equals("hz", item)) {
                        redisTemplate.delete(item);
                    }
                    log.info(" keys - > {} ", item);
                }
        );
    }
}
  • GEORADIUSBYMEMBER 方法过期了,这里就不演示了。

End

最近更新: 2025/12/27 18:51
Contributors: 庆峰
Prev
Java 雪花算法
Next
网络通信 Tcpdump