GEO

介绍

Redis GEO 是Redis3.2版本新增的数据类型,主要用于存储地理位置信息,并对存储的信息进行操作。

在日常生活中,我们越来越依赖搜索“附件的餐馆”、在打车软件上叫车,这些都离不开基于位置信息服务(Location-Based Service,LBS)的应用。LBS应用访问的数据时和人或物关联的一组经纬度信息,而且要能查询相邻的经纬度范围,GEO就非常适合应用在LBS服务的场景中。

内部实现

GEO 本身并没有新的底层数据结构,而是直接使用了Sorted Set集合类型。

GEO类型使用GeoHash编码方法实现了经纬度到Sorted Set中元素权重分数的转换,这其中两个关键机制就是[对二维地图做区间划分]和[对区间进行编码]。一组经纬度落在某个区间后,就用区间的编码值来表示,并把编码值作为Sorted Set元素的权重分数。

这样一来,我们就可以把经纬度保存到Sorted Set中,利用Sorted Set提供的“按权重进行有序范围查找”的特性,实现LBS服务中频繁使用的“搜索附近”的需求

常用命令

# 存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的key中
GEOADD key longitude latiude member [longitude latitude member ...]

# 从给定的key里返回所有指定名称(member)的位置(经度和纬度),不存在返回nil
GEOPOS key member [member ...]

# 返回两个定位置之间的距离
GEODIST key member1 member2 [m|km|ft|mi]

# 根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STOREDIST key]

应用场景

滴滴叫车

这里以滴滴叫车的场景为例,介绍下具体如何使用GEO命令:GEOADD和GEORADIUS这两命令。

假设车辆ID是33,经纬度位置是(116.034579,39.0304052),我们可以用一个GEO集合保存所有车辆的经纬度,集合key是cars:locations.

执行下面这个命令,就可以把ID号为33的车辆的当前经纬度位置存入GEO集合中:

GEOADD cars:locations 116.034579 39.0304052 33

当用户想寻找自己附近的车是,LBS应用就可以使用GEORADIUS命令

例如,LBS应用执行下面的命令时,Redis会根据输入的用户的经纬度信息(116.034579,39.0304052),查找这个经纬度为中心的5公里内车辆信息,并返回个LBS应用

GEORADIUS cars:locations 116.034579 39.0304052 5 km ASC COUNT 10
Last modification:May 31, 2024
如果觉得我的文章对你有用,请收藏本站