最近在做一款交友软件的APP,现在有一个功能需要实现搜索附近的人。后来发现用redis 的GEO功能实现非常简单。

先说一下设计思路,每个用户在登陆的时候都会添加一下经纬度,这个是APP端获取的,然后设置一下这个经纬度到mysql数据库中,最后把经纬度同步到redis数据库中。我们先来了解一下 redis GEO功能。

我们在用到redis的geo功能时候一定要把版本设置到3.2版本以上,3.2版本以上才有这些方法。

核心的用到的pom配置

 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.4.2</version></dependency>

核心方法

geoadd:增加某个地理位置的坐标。
geopos:获取某个地理位置的坐标。
geodist:获取两个地理位置的距离。
georadius:根据给定地理位置坐标获取指定范围内的地理位置集合。
georadiusbymember:根据给定地理位置获取指定范围内的地理位置集合。
geohash:获取某个地理位置的geohash值。

具体实现代码:

实体类:

package com.example.demo.entity;import lombok.Data;/*** @author XuYangWei* @Description:* @Date 2021/7/21 11:41*/
@Data
public class Coordinate {double latitude;double longitude;String key;
}

工具包:

package com.example.demo.utils;import com.example.demo.entity.Coordinate;
import redis.clients.jedis.*;
import redis.clients.jedis.params.GeoRadiusParam;import java.util.List;public class RedisUtil {private static JedisPool jedisPool = null;// Redis服务器IP  private static String ADDR = "127.0.0.1";// Redis的端口号  private static int PORT = 6379;// 访问密码
//        private static String AUTH = "";/** * 初始化Redis连接池 */  static {  try {  JedisPoolConfig config = new JedisPoolConfig();// 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true  config.setBlockWhenExhausted(true);  // 设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)  config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");  // 是否启用pool的jmx管理功能, 默认true  config.setJmxEnabled(true);  // 最大空闲连接数, 默认8个 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。  config.setMaxIdle(8);  // 最大连接数, 默认8个  config.setMaxTotal(200);  // 表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;  config.setMaxWaitMillis(1000 * 100);  // 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;  config.setTestOnBorrow(true);  jedisPool = new JedisPool(config, ADDR, PORT, 3000);} catch (Exception e) {  e.printStackTrace();  }  }  /** * 获取Jedis实例 *  * @return */  public synchronized static Jedis getJedis() {  try {  if (jedisPool != null) {  Jedis resource = jedisPool.getResource();  return resource;  } else {  return null;  }  } catch (Exception e) {  e.printStackTrace();  return null;  }  }  /** * 释放jedis资源 *  * @param jedis */  public static void close(final Jedis jedis) {  if (jedis != null) {  jedis.close();  }  }  /** * 添加坐标 * key 经度  维度  距离 * return m 表示单位为米*/  public static Long addReo(Coordinate coordinate) {  Jedis jedis = null;  try {  jedis = jedisPool.getResource();  //第一个参数可以理解为表名  return jedis.geoadd("test",coordinate.getLongitude(),coordinate.getLatitude(),coordinate.getKey());  } catch (Exception e) {  System.out.println(e.getMessage());  } finally {  if (null != jedis)  jedis.close();  }  return null;  }  /** * 查询附近人 * key 经度  维度  距离 * return GeoRadiusResponse*/  public static List<GeoRadiusResponse> geoQuery(Coordinate coordinate) {Jedis jedis = null;  try {  jedis = jedisPool.getResource();  //200F GeoUnit.KM表示km   return jedis.georadius("test",coordinate.getLongitude(),coordinate.getLatitude(),200F, GeoUnit.KM, GeoRadiusParam.geoRadiusParam().withDist());} catch (Exception e) {  System.out.println(e.getMessage());  } finally {  if (null != jedis)  jedis.close();  }  return null;  }}  

测试方法:

package com.example.demo;import com.example.demo.entity.Coordinate;
import com.example.demo.utils.RedisUtil;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.Jedis;import java.util.List;import static com.example.demo.utils.RedisUtil.addReo;
import static com.example.demo.utils.RedisUtil.geoQuery;/*** @author XuYangWei* @Description:* @Date 2021/7/21 11:48*/
public class TestRedis {public static void main(String[] args) {Jedis jedis = RedisUtil.getJedis();java.text.DecimalFormat df = new java.text.DecimalFormat("#.######");//保留六位小数//添加经纬度Coordinate coordinate = new Coordinate();coordinate.setLatitude(31.244803);  //维度coordinate.setLongitude(121.483671); //经度coordinate.setKey("1");  //可以作为用户表的id//添加经纬度Coordinate coordinate1 = new Coordinate();coordinate1.setLatitude(31.245321);  //维度coordinate1.setLongitude(121.485015); //经度coordinate1.setKey("2");  //可以作为用户表的id//添加经纬度Coordinate coordinate2 = new Coordinate();coordinate2.setLatitude(31.245456);  //维度coordinate2.setLongitude(121.485285); //经度coordinate2.setKey("3");  //可以作为用户表的idaddReo(coordinate);addReo(coordinate1);addReo(coordinate2);//添加经纬度coordinate.setLatitude(31.244803);  //维度coordinate.setLongitude(121.483671); //经度coordinate.setKey("1");  //用户表的id 以当前用户作为查询条件,查询他周围的人数List<GeoRadiusResponse> list = geoQuery(coordinate);for (GeoRadiusResponse geo : list) {System.out.println(geo.getMemberByString()); //主键 有主键了个人信息就很简单了System.out.println(df.format(geo.getDistance()));  //距离多少米}RedisUtil.close(jedis);}
}

打印效果:

redis实现“附近的人”相关推荐

  1. Spring boot基于redis实现附近的人(附源码下载)

    此文章是针对去年写的Java基于Redis实现"附近的人 进行业务优化! 核心源码 public class NearbyPO {@NotNull(message = "id值不能 ...

  2. SpringBoot + Redis:模拟 10w 人的秒杀抢单!

    欢迎关注方志朋的博客,回复"666"获面试宝典 作者:神牛003 来源:cnblogs.com/wangrudong003/p/10627539.html 本篇内容主要讲解的是re ...

  3. Spring Boot + Redis:模拟 10w 人的秒杀抢单!

    作者 | 神牛003 来源 | www.cnblogs.com/wangrudong003/p/10627539.html 本篇内容主要讲解的是redis分布式锁,这个在各大厂面试几乎都是必备的,下面 ...

  4. 使用redis实现5万人同服的“相位技术”

    魔兽世界和EVE服务器能够同时支持5万人在线的技术肯定让很多人流口水吧.今天我用redis来模拟实现"相位技术".所谓"相位技术"就是将服务器分为多个并行的空间 ...

  5. Java基于Redis实现附近的人(内附源码)

    前几天收到一个新的需求,需要实现类似"附近的人"的功能:根据自己当前的定位,获取距离范围内的所有任务地点.刚看到这个需求时有点懵逼,第一想到的就是要利用地球的半径公式去计算距离,也 ...

  6. 使用Redis实现附近的人及打车服务

    面向LBS应用的GEO数据类型 各种社交软件里面都有附件的人的需求,在该应用中,我们查询附近 1 公里的食客,同时只需查询出 20 个即可. 这都依赖基于位置信息服务(Location-Based S ...

  7. Java基于Redis实现“附近的人”(含源码下载)

    "附近的人"在社交类APP已成为标配的功能,Low一点的实现方式可以把坐标存至关系型数据库,通过计算的坐标点距离实现,这种计算可行但计算速度远不及内存操作级别的NoSql数据库. ...

  8. 【Redis】实现附近人功能

    01 Redis的Geo 最近在写实现附近人的这个功能,在网上找了很多方案,但是都不尽人意.最后发现了redis已经实现了这个功能.支持存储地理位置信息来实现附近位置,摇一摇这类依赖于地理位置信息的功 ...

  9. 如何用 Redis 查询 “附近的人” ?

    点击关注公众号:互联网架构师,后台回复 2T获取2TB学习资源! 上一篇:Alibaba开源内网高并发编程手册.pdf 来源:juejin.cn/post/6844903966061363207 作者 ...

  10. 如何使用 Redis 实现 “附近的人” 这个功能?

    点击关注公众号,实用技术文章及时了解 作者简介 万汨,饿了么资深开发工程师.iOS,Go,Java均有涉猎.目前主攻大数据开发.喜欢骑行.爬山. 前言:针对"附近的人"这一位置服务 ...

最新文章

  1. SQLserver数据库操作帮助类SqlHelper
  2. ORACLE开发:创建与管理表空间和数据文件1
  3. gcc 4.4.2 安装
  4. python单例_Python - 单例模式(Singleton)
  5. linux-三个文件-用户文件-组文件-密码文件
  6. RSA加密算法的简单案例
  7. Java案例:Swing摇奖器
  8. 【java】Java 8 - 移除Permgen 使用元空间
  9. Echart.js的趋势图入门与实例
  10. Java NIO 和 IO的区别
  11. 计算机网络知识汇总(超详细整理)
  12. 萌新分享打印当前目录下的所有文件和打印出里面java文件的代码
  13. 供应链金融与区块链01——论文阅读
  14. 计算机软件公司用ps是,[计算机软件及应用]ps婚纱.doc
  15. Java聊天室——一对一模式
  16. 细致的网站开发流程是怎样的?
  17. Android 11 Audio框架探索之AudioTracK(二)
  18. 群体遗传,进化分析利器Popgene分享给大家
  19. 《AutoCAD .NET开发指南2012版》翻译整理已完成,欢迎大家下载!
  20. 不太吸引人的成就系统

热门文章

  1. java年份判断_java怎么判断年份是否是闰年
  2. 输入年份判断是不是闰年
  3. 跟驰理论 matlab,[经济学]第5章 跟驰理论.ppt
  4. 西方经济学高鸿业第7版复习资料合集
  5. revi翻模工具【管线角度微调】,那些最不擅长的小事
  6. 前端进击的巨人(三):从作用域走进闭包
  7. Oracle Goldengate 12c打pus补丁
  8. Hadoop 基本常用命令
  9. Matlab里for循环详解
  10. 北京兄弟连web前端