打开美团,可以通过自身定位查看附近的商品。打开社交软件,可以查看附近的人交友。打开滴滴,可以查看的附近的共享单车,那这些是如何实现?
Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。
Redis GEO 操作方法有:
先用百度地图提供的经纬度查询工具 拾取坐标系统,准备一些坐标信息:
选择三个点的坐标作为测数据,如下
地点 | 坐标 |
---|---|
翠湖公园(a) | 102.710039,25.054179 |
大观公园(b) | 102.679209,25.027989 |
动物园? | 102.714992,25.061773 |
geoadd
geoadd 用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。
geoadd 语法格式如下:
GEOADD key longitude latitude member [longitude latitude member ...]
重点参数说明如下:
此命令支持一次添加一个或多个位置信息。
以下实例中key为km
geoadd km 102.710039 25.054179 "a"
geoadd km 102.679209 25.027989 "b"
geoadd km 102.714992 25.061773 "c"
geopos
geopos 用于从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。
geopos 语法格式如下:
GEOPOS key member [member ...]
此命令支持查看一个或多个位置信息
127.0.0.1:6379> geopos km a
1) 1) "102.69033282995223999"
2) "25.04997624927904809"
geodist
geodist 用于返回两个给定位置之间的距离。
geodist 语法格式如下:
GEODIST key member1 member2 [m|km|ft|mi]
member1 member2 为两个地理位置。
最后一个距离单位参数说明:
m :米,默认单位。
km :千米。
mi :英里。
ft :英尺。
# 计算翠湖公园(a)到大观公园(b)的距离,单位km
127.0.0.1:6379> geodist km a b km
"4.2587"
计算翠湖公园(a)到大观公园(b)的距离是4.25公里,跟地图比对,结果基本吻合
georadius
以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
georadiusbymember
georadiusbymember 和 georadius 命令一样, 都可以找出位于指定范围内的元素, 但是 georadiusbymember 的中心点是由给定的位置元素决定的, 而不是使用经度和纬度来决定中心点。georadius 与 georadiusbymember 语法格式如下:
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
参数说明:
根据给定的经纬度坐标查询附近的成员
# 根据查询的坐标,查询5km以内的成员信息
127.0.0.1:6379> georadius km 102.705224 25.0499233 5 km
1) "b"
2) "a"
3) "c"
# 根据坐标查询5km以内的成员信息,并返回位置元素与中心之间的距离
127.0.0.1:6379> georadius km 102.705224 25.0499233 5 km withdist
1) 1) "b"
2) "3.5812"
2) 1) "a"
2) "0.6776"
3) 1) "c"
2) "1.6450"
#根据坐标查询5km以内的成员信息,并返回位置元素与中心之间的距离,从近到远,返回2个成员
georadius km 102.705224 25.0499233 5 km withdist count 2 asc
1) 1) "a"
2) "0.6776"
2) 1) "c"
2) "1.6450"
# 根据成员的坐标查询5km以内的成员信息,并返回位置元素与中心之间的距离,从近到远,返回2个成员
127.0.0.1:6379> georadiusbymember km a 5 km withdist count 2 asc
1) 1) "a"
2) "0.0000"
2) 1) "c"
2) "0.9813"
zrem
删除地理位置信息
zrem key member [member ...]
比如c成员的坐标信息
127.0.0.1:6379> zrem km c
(integer) 1
引入jedis
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.1.0</version>
</dependency>
查找附近的门店,本地生活这种场景特别多。
我想喝一杯瑞幸咖啡,打开瑞幸的微信小程序,根据自身当前定位,查看下我附近都有哪些门店,哪个离我最近,那我就在哪个门店下单。
public static void main(String[] args) {
Jedis jedis = new Jedis("10.1.250.157",6379);
jedis.auth("google00");
//添加门店a
jedis.geoadd("store",102.710039,25.054179,"a");
//添加门店b
jedis.geoadd("store",102.679209,25.027989,"b");
//添加门店c
jedis.geoadd("store",102.714992 ,25.061773,"c");
//我当前定位的坐标,查询附近的门店,从近到远的门店,并显示距离
GeoRadiusParam geoRadiusParam = new GeoRadiusParam();
geoRadiusParam.withDist().sortAscending();
List<GeoRadiusResponse> storeList = jedis.georadius("store",102.705224 ,25.0499233,5,GeoUnit.KM,geoRadiusParam);
for (GeoRadiusResponse r : storeList) {
System.out.println("门店"+r.getMemberByString()+" 距离我:"+r.getDistance()+"km");
}
}
结果:
门店a 距离我:0.6776km
门店c 距离我:1.645km
门店b 距离我:3.5812km
注意点:所有门店数据放入到store这个key里,查询如果频繁,这个key容易成为热key,可以使用redis集群,同样的数据多设置几个key,比如:store_1,store_2,store_3 ,查询的时候可以根据用户id取余,命中不同的key查询
社交软件,经常看到附近的人,怎么做呢
public static void main(String[] args) {
Jedis jedis = new Jedis("10.1.250.157",6379);
jedis.auth("google00");
//添加张三
jedis.geoadd("person_member",102.710039,25.054179,"zhangsan");
//添加小明
jedis.geoadd("person_member",102.679209,25.027989,"xiaoming");
//添加李四
jedis.geoadd("person_member",102.714992 ,25.061773,"lisi");
//我当前定位的坐标,查询附近5km范围内的人,从近到远排序,并显示距离
GeoRadiusParam geoRadiusParam = new GeoRadiusParam();
geoRadiusParam.withDist().sortAscending();
List<GeoRadiusResponse> storeList = jedis.georadius("person_member",102.705224 ,25.0499233,5,GeoUnit.KM,geoRadiusParam);
for (GeoRadiusResponse r : storeList) {
System.out.println(r.getMemberByString()+" 距离我:"+r.getDistance()+"km");
}
}
结果
zhangsan 距离我:0.6776km
lisi 距离我:1.645km
xiaoming 距离我:3.5812km
计算两个坐标之间的距离
public static void main(String[] args) {
Jedis jedis = new Jedis("10.1.250.157",6379);
jedis.auth("google00");
//添加张三
jedis.geoadd("person_member",102.710039,25.054179,"zhangsan");
//添加小明
jedis.geoadd("person_member",102.679209,25.027989,"xiaoming");
//添加李四
jedis.geoadd("person_member",102.714992 ,25.061773,"lisi");
//我当前定位的坐标,查询附近5km的人,从近到远排序,并显示距离
GeoRadiusParam geoRadiusParam = new GeoRadiusParam();
geoRadiusParam.withDist().sortAscending();
Double dist = jedis.geodist("person_member","xiaoming","lisi",GeoUnit.KM);
System.out.println("xiaoming与lisi距离:"+dist+"km");
}
结果:
zhangsan与lisi距离:5.208km
写作不易,刚好你看到,刚好对你有帮助,动动小手,点点赞,欢迎转发,有疑问的欢迎留言或者私信讨论,有问必回。