Redis--Geo指令的语法和使用场景举例(附近的人功能)

news2024/9/30 13:20:31

文章目录

      • 前言
      • 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深度历险 核心原理与应用实践》–钱文品

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

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

相关文章

jrebel IDEA 热部署

1 下载 2022.4.1 JRebel and XRebel - IntelliJ IDEs Plugin | Marketplace 2 选择下载好的zip 离线安装IDEA 插件 重启IDEA 3 打开 [Preference -> JRebel & XRebel] 菜单&#xff0c;输入 GUID address 为 https://jrebel.qekang.com/1e67ec1b-122f-4708-87d…

尚硅谷Nginx高级配置笔记

写在前面&#xff1a;本笔记是学习尚硅谷nginx可成的时候的笔记&#xff0c;不是原创&#xff0c;如有需要&#xff0c;可以去官网看视频&#xff0c;以下是pdf文件 Nginx高级 第一部分&#xff1a;扩容 通过扩容提升整体吞吐量 1.单机垂直扩容&#xff1a;硬件资源增加 云…

[HTML]Web前端开发技术14(HTML5、CSS3、JavaScript )鼠标经过图片显示大图 网页标题:表格标签的综合应用——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

Flink TaskManager内存管理机制介绍与调优总结

内存模型 因为 TaskManager 是负责执行用户代码的角色&#xff0c;一般配置 TaskManager 内存的情况会比较多&#xff0c;所以本文当作重点讲解。根据实际需求为 TaskManager 配置内存将有助于减少 Flink 的资源占用&#xff0c;增强作业运行的稳定性。 TaskManager 内…

Docker(二)安装指南:主要介绍 Docker 在 Linux 、Windows 10 和 macOS 上的安装

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; 安装 Docker Docker 分为 stable test 和 nightly 三个更新频道。 官方网站上有各种环境下的 安装指南&#xff0c;这里主要介绍 Docker 在…

没有统计学背景的人学六西格玛:挑战与机遇并存

在当今追求高效率、高品质的时代&#xff0c;六西格玛方法已成为企业提升竞争力的关键法宝。但对于众多没有统计学背景的朋友来说&#xff0c;这一方法仿佛高不可攀。今天&#xff0c;就让我们一同探索&#xff0c;没有统计学背景的人学习六西格玛到底难不难&#xff1f; 一、难…

el-table实现搜索高亮展示并滚动到元素位置

效果展示&#xff1a; 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"wid…

年龄性别预测2:Pytorch实现年龄性别预测和识别(含训练代码和数据)

年龄性别预测2&#xff1a;Pytorch实现年龄性别预测和识别(含训练代码和数据) 目录 年龄性别预测2&#xff1a;Pytorch实现年龄性别预测和识别(含训练代码和数据) 1.年龄性别预测和识别方法 2.年龄性别预测和识别数据集 3.人脸检测模型 4.年龄性别预测和识别模型训练 &a…

Oracle行转列函数,列转行函数

Oracle行转列函数&#xff0c;列转行函数 Oracle 可以通过PIVOT,UNPIVOT,分解一行里面的值为多个列,及来合并多个列为一行。 PIVOT PIVOT是用于将行数据转换为列数据的查询操作(类似数据透视表)。通过使用PIVOT&#xff0c;您可以按照特定的列值将数据进行汇总&#xff0c;并将…

Maxwell介绍

一、介绍 介绍&#xff1a;它读取MySQL binlog并将数据更改作为JSON写入Kafka、Kinesis和其他流媒体平台&#xff08;目前支持&#xff1a;kafka、RabbitMQ、Redis、file、Kinesis、Nats、Google Cloud Pub/Sub、Google Cloud Bigquery、SNS&#xff09; 版本&#xff1a;从v1.…

Git教程学习:01 Git简介与安装

目录 1 版本控制1.1 什么是版本控制系统&#xff1f;1.2 本地版本控制系统1.3 集中式版本控制系统1.4 分布式版本控制系统 2 Git简史3 Git的安装3.1 在Linux上安装3.2 初次运行Git前的配置 1 版本控制 1.1 什么是版本控制系统&#xff1f; 版本控制系统(Version Control Syst…

css 居中方式

居中分为水平居中和垂直居中 1. 水平居中1.1 文字text-align:center;1.2 盒子1.2.1&#xff1a;inline-block text-align 一 center;1.2.2&#xff1a;absolutetransform 一 父元素 display:relative;子元素 display:absolute; left:50%;transform: translatex(-50%);1.2.3&a…

一个好用的工具,对网工来说是绝杀技!

上午好&#xff0c;我是老杨。 提到用人&#xff0c;很多单位和管理者第一反应都是应聘者的能力。能力到底怎么界定&#xff0c;其实每个人都有不同的判定标准。 在我看来&#xff0c;做事专注&#xff0c;且能尽可能“偷懒”的网工 &#xff0c;就是我个人筛选员工的标准。 …

游戏开发要注意这几个问题

游戏开发是一个充满创意和挑战的过程。对于初学者和经验丰富的开发者来说&#xff0c;每个项目都是一个新的学习机会。然而&#xff0c;成功的游戏开发不仅仅是关于编码和设计&#xff1b;它还涉及到细致的规划、测试和市场洞察。以下是在开发游戏时需要特别注意的几个关键方面…

CentOS stream 9配置网卡

CentOS stream9的网卡和centos 7的配置路径&#xff1a;/etc/sysconfig/network-scripts/ifcfg-ens32不一样。 CentOS stream 9的网卡路径&#xff1a; /etc/NetworkManager/system-connections/ens32.nmconnection 方法一&#xff1a; [connection] idens32 uuid426b60a4-4…

区间预测 | Matlab实现LSTM-Adaboost-ABKDE的集成学习长短期记忆神经网络自适应带宽核密度估计多变量回归区间预测

区间预测 | Matlab实现LSTM-Adaboost-ABKDE的集成学习长短期记忆神经网络自适应带宽核密度估计多变量回归区间预测 目录 区间预测 | Matlab实现LSTM-Adaboost-ABKDE的集成学习长短期记忆神经网络自适应带宽核密度估计多变量回归区间预测效果一览基本介绍程序设计参考资料 效果一…

npm install 安装出错时尝试过的方法

使用npm cache clean --force清除缓存&#xff0c;然后将安装失败的项目中的node_modules文件夹以及package-lock.json文件删除&#xff08;package-lock.json是在npm install安装时生成的一份文件&#xff0c;用以记录当前状态下实际安装的各个npm package的具体来源和版本号&…

探索设计模式的魅力:抽象工厂模式的艺术

抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;用于在不指定具体类的情况下创建一系列相关或相互依赖的对象。它提供了一个接口&#xff0c;用于创建一系列“家族”或相关依赖对象&#xff0c;而无需指定它们的具体类。 主要参…

Linux安装ossutil工具且在Jenkins中执行shell脚本下载文件

测试中遇到想通过Jenkins下载OSS桶上的文件&#xff0c;要先在linux上安装ossutil工具&#xff0c;记录安装过程如下&#xff1a; 一、下载安装ossutil&#xff0c;使用命令 1.下载&#xff1a;wget https://gosspublic.alicdn.com/ossutil/1.7.13/ossutil64 2.一定要赋权限…

大创项目推荐 深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的视频多目标跟踪实现 …