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

这篇具有很好参考价值的文章主要介绍了Redis--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} 上进行定位,得到经纬度坐标

    Redis--Geo指令的语法和使用场景举例(附近的人功能),Redis,redis,数据库,缓存

  • 指定圆心半径,找到该圆范围内的所有元素,并按与圆心距离排序后返回: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以内的人有哪些,运行结果如下:
    Redis--Geo指令的语法和使用场景举例(附近的人功能),Redis,redis,数据库,缓存文章来源地址https://www.toymoban.com/news/detail-806582.html

参考文献

  • 《91.Redis深度历险 核心原理与应用实践》–钱文品

到了这里,关于Redis--Geo指令的语法和使用场景举例(附近的人功能)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java实战:Redis实现查找附近的人

    本文将介绍如何使用Redis实现查找附近的人的功能。我们将探讨如何使用Redis的地理空间(Geospatial)索引功能,并展示一个简单的Java代码示例,该示例使用Jedis库和Redis的GEOADD命令来添加位置信息,以及使用GEORADIUS命令来查找附近的人。通过本文,可以了解到如何在Java应用程

    2024年02月21日
    浏览(37)
  • 【案例实战】SpringBoot整合Redis的GEO实现查找附近门店功能

    像我们平常美团点外卖的时候,都会看到一个商家距离我们多少米。还有类似QQ附近的人,我们能看到附近的人距离我们有多少米。 那么这些业务是怎么做的呢?是如何实现 基于位置的附近服务 系统呢。 在去了解基于位置的附近服务之前,我们先来看一下什么是GIS技术。

    2024年02月10日
    浏览(36)
  • Redis--Zset使用场景举例(滑动窗口实现限流)

    前言 在Redis–Zset的语法和使用场景举例(朋友圈点赞,排行榜)一文中,提及了redis数据结构zset的指令语法和一些使用场景,今天我们使用zset来实现滑动窗口限流,详见下文。 什么是滑动窗口 滑动窗口是一种流量控制策略,用于控制一定时间内请求的访问数量。 其原理是

    2024年01月19日
    浏览(52)
  • SQL的五大约束作用、语法、应用场景及举例

    SQL的五大约束包括 主键约束(PRIMARY KEY)、唯一性约束(UNIQUE)、外键约束(FOREIGN KEY)、非空约束(NOT NULL)和默认约束(DEFAULT) 。 sql约束的作用:主要是 保证数据的完整性、准确性和一致性 ,从而 确保 数据库中存储的 数据质量 。 温馨提示:以下举例为mysql版本,若您

    2024年01月21日
    浏览(50)
  • Redis常用命令指令、描述及简单举例

    指令 描述 举例 set 存入单个数据 set number 1 setex 存入并设置过期时间 setex key 30 value setnx 不存在则存入,实现分布式锁 setnx key value msetnx 不存在则批量存入,原子性操作 msetnx key1 value1 key2 value2 有一个key存在则整个语句插入失败 mset 批量存入数据 mset key1 1 key2 2 get 获取单个数据

    2024年01月22日
    浏览(43)
  • MySQL 实战(一):实现“附近的人”功能

    ❤️ 个人主页:水滴技术 🚀 支持水滴: 点赞 👍 + 收藏 ⭐ + 留言 💬 🌸 订阅专栏:MySQL 教程:从入门到精通 大家好,我是水滴~~ 对于“附近的人”功能,在生活中是比较常用的,像外卖app附近的美食,共享单车app里附近的车辆等等。我们之前使用 ElasticSearch 实现过该功

    2024年02月11日
    浏览(39)
  • prisma 结合 mongodb 查询地理空间坐标,实现 “附近的人”功能

    前言:我们创建一个集合,添加测试数据,并执行 mongodb 的地理空间查询,返回需要的数据。 1、通过 schema.prisma , 创建 store 集合 2、通过 prisma/client ,插入 几条测试数据 location 的数据格式为 GeoJSON ,即地理位置信息的 JSON 表示法。 这里 type 指定类型为 点坐标 , coordinates

    2024年02月10日
    浏览(45)
  • Elasticsearch集群搭建、数据分片以及位置坐标实现附近的人搜索

    es使用两种不同的方式来发现对方: 广播 单播 也可以同时使用两者,但默认的广播,单播需要已知节点列表来完成 当es实例启动的时候,它发送了广播的ping请求到地址 224.2.2.4:54328 。而其他的es实例使用同样的集群名称响应了这个请求。 一般这个默认的集群名称就是上面的

    2024年02月06日
    浏览(50)
  • 如何使用Redis实现附近商家查询

    🔥🔥宏夏Coding网站,致力于为编程学习者、互联网求职者提供最需要的内容!网站内容包括求职秘籍,葵花宝典(学习笔记),资源推荐等内容。在线阅读:https://hongxiac.com🔥🔥 在日常生活中,我们经常能看见查询附近商家的功能。 常见的场景有,比如你在点外卖的时候

    2024年02月12日
    浏览(52)
  • 阿里云服务器可以做什么?十大使用场景举例说明

    使用阿里云服务器可以做什么?阿里云百科分享使用阿里云服务器常用的十大使用场景,说是十大场景实际上用途有很多,阿里云百科分享常见的云服务器使用场景,如本地搭建ChatGPT、个人网站或博客、运维测试、学习Linux、跑Python、小程序服务器等等,阿小云分享使用阿里

    2024年02月10日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包