0%

Redis系列第五篇之Geo

前言

Redis Commands页面中,Redis还提供了一种名为Geospatial indices的命令,该命令是用于地理空间索引,目的是为了方便在给定的地理半径内查找位置。调用方可以通过GEOADD添加地理位置,通过GEORADIUS命令来查找指定半径范围内的位置。虽然Redis将其定义为地理空间索引,但实质上此命令对应的数据类型为Sorted Set(有序集合)。接下来是地理位置空间索引相关的命令~

GEOADD key [ NX | XX] [CH] longitude latitude member [ longitude latitude member …]

  • 可用版本: v3.2.0开始
  • 历史: v6.2.0开始增加CHNXXX选项
  • 时间复杂度: 每添加一个新项的复杂度为O(log(N)),其中N为key对应的有序集合中既有的元素数量
  • 解释: 向指定key添加新的地理位置项(经度、纬度、名称),添加的数据被存储在有序集合中,可以通过GEOSEARCH命令进行查询,如果需要删除坐标,则需要调用ZREM命令。命令严格按照(x, y)坐标系的格式进行参数传递,所以经度必须放在纬度之前。Geospatial Indexes无法索引非常靠近两极的坐标,如果经纬度超过下面指定的经纬度范围,命令将会报错:
    1. 有效的经度范围为:-180~180度
    2. 有效的纬度范围为:-85.05112878~85.05112878度
  • 选项说明
    1. XX: 不添加新元素,只更新既有的元素
    2. NX: 不更新既有元素,只添加新元素
    3. CH: 将返回值由新添加的元素数量改为变更过的元素数量(同时包含新增的元素和变更的数量)
  • 返回值: Integer(整型),如果没有使用选项参数,将返回新增的元素数量(不包含分数更新),当指定CH选项时,将会返回变更元素的数量(同时包含新增和更新)

GEODIST key member1 member2 [ M | KM | FT | MI]

  • 可用版本: v3.2.0开始
  • 时间复杂度: O(log(N))
  • 解释: 返回key对应的地理位置集合中两个成员之间的距离,由于计算是基于假设地球为一个完美的球体这样的假设,所以在极端情况下计算结果可能会存在%0.5的误差。返回值的单位由命令参数选项指定:
  • 选项说明:
    1. M: 单位:米
    2. KM: 单位:公里(千米)
    3. FT: 单位:英里
    4. MI: 单位:英尺
  • 返回值: Bulk String(批量字符串),返回可以转换为双精度浮点型的字符串,如果一个或者两个元素丢失,将会返回nil。

GEOHASH key member [member …]

  • 可用版本: v3.2.0开始
  • 时间复杂度: 单个member的复杂度为O(log(N)),其中N为有序集合中的元素数量
  • 解释: 返回指定成员对应的地理位置的GEOHASH值,Redis使用的是GEOHASH的变种技术,即使用52位整数对位置进行编码,Redis返回的GEOHASH值的特性如下:
    1. GEOHASH值长度为11位
    2. 可以通过从GEOHASH值的右侧删除字符来缩短GEOHASH值,虽然会产生精度丢失,但仍然指向同一个区域。
    3. 可以在 geohash.org URL中使用它们
    4. 具有相似前缀的GEOHASH字符串位置相近,同时前缀不同的位置也可能在附近
  • 返回值: Array(数组),每个元素为位置成员对应的GEOHASH值,返回顺序与命令传递的成员顺序一致。

GEOPOS key member [member …]

  • 可用版本: v3.2.0开始
  • 时间复杂度: O(N),N为请求的member数量
  • 解释: 返回地理位置集合中指定成员的位置(经度,纬度)。
  • 返回值: Array(数组),返回数组,数组中每个元素为一个拥有两个元素的子数组,两个元素分别为(经度和纬度)。需要注意的是,即使命令传递的member数量为1,返回值类型也为数组

GEORADIUS key longitude latitude radius M | KM | FT | MI [WITHCOORD] [WITHDIST] [WITHHASH] [ COUNT count [ANY]] [ ASC | DESC] [STORE key] [STOREDIST key]

  • 可用版本: v3.2.0开始,v6.2.0开始此命令被视为废弃,可以用GEOSEARCHGEOSEARCHSTORE代替
  • 历史: v6.2.0开始为COUNT参数添加了ANY选项
  • 时间复杂度: O(N+log(M)),其中N为指定范围内(由给定位置和半径构成的圆形区域)的元素数量,M为索引的项目数
  • 解释: 返回指定区域内的地理位置成员,区域范围以给定的经纬度为中心,radius为半径构成的圆形区域。指定的半径长度单位可以是:
  • 选项说明:
    1. radius长度单位说明:
      • M: 单位:米
      • KM: 单位:公里(千米)
      • FT: 单位:英里
      • MI: 单位:英尺
    2. with选项说明:
      • WITHDIST: 同时返回匹配项与中心点的距离,距离单位与命令指定的半径单位相同
      • WITHCOORD: 同时返回匹配项的经纬度坐标
      • WITHHASH: 同时返回匹配项的GEOHASH值
    3. 默认返回的匹配项是基于中心距离无序的,匹配项返回顺序说明:
      • ASC: 按照距离中心点由近到远的顺序排序
      • DESC: 按照距离中心距离由远到近的顺序排序
    4. 命令默认返回区域内所有的匹配项,调用方可以通过COUNT参数指定需要返回的匹配项数量,当COUNT参数被提供了ANY参数时,命令将会尽快返回,即只要匹配项个数满足COUNT后立即返回。
    5. 默认情况下,命令会将结果返回给客户端,但如果指定了存储选项,命令会将结果存储进对应的配置里
      • STORE 与原有序集合一样,存储地理位置的位置信息
      • STOREDIST 将匹配项距离中心点的距离作为分数存储进有序集合中
  • 返回值: Array(数组)
    • 如果指定了STORE或者STOREDIST选项,命令将会返回存储进目标键中的项目数
    • 没有指定WITH选项时,命令仅仅返回由位置名称组成的数组: [“北京”,”上海”,”广州”,深圳”]
    • 如果指定了WITHCORRDWITHDISTWITHHASH选项时,命令返回数组,数组的每个元素代表一个地理位置,其中包括名称、经纬度、距离中心点的距离、GEOHASH值等(具体内容视参数选项而定),作为规定,子数组里每个元素的顺序是固定的,根据指定的参数选项,可能会没有某些值,但整体顺序保持不变(具体视给定的命令参数选项而定):
      1. 位置名称
      2. 与中心点的距离,单位与命令中的半径单位保持一致
      3. 位置的经纬度(经度,纬度)

GEORADIUS_RO key longitude latitude radius M | KM | FT | MI [WITHCOORD] [WITHDIST] [WITHHASH] [ COUNT count [ANY]] [ ASC | DESC]

  • 可用版本: v3.2.10开始,v6.2.0开始被视为废弃,可以用GEOSEARCH命令代替
  • 历史: v6.2.0开始为COUNT参数添加了ANY选项
  • 时间复杂度: O(N+log(M)),其中N为指定范围内(由给定位置和半径构成的圆形区域)的元素数量,M为索引的项目数
  • 解释: 此命令为=GEORADIUS的只读版本,所以唯一区别在于此命令不支持STORESTOREDIST参数
  • 返回值:
    • 没有指定WITH选项时,命令仅仅返回由位置名称组成的数组: [“北京”,”上海”,”广州”,深圳”]
    • 如果指定了WITHCORRDWITHDISTWITHHASH选项时,命令返回数组,数组的每个元素代表一个地理位置,其中包括名称、经纬度、距离中心点的距离、GEOHASH值等(具体内容视参数选项而定),作为规定,子数组里每个元素的顺序是固定的,根据指定的参数选项,可能会没有某些值,但整体顺序保持不变(具体视给定的命令参数选项而定):
      1. 位置名称
      2. 与中心点的距离,单位与命令中的半径单位保持一致
      3. 位置的经纬度(经度,纬度)

GEORADIUSBYMEMBER key member radius M | KM | FT | MI [WITHCOORD] [WITHDIST] [WITHHASH] [ COUNT count [ANY]] [ ASC | DESC] [STORE key] [STOREDIST key]

  • 可用版本: v3.2.0开始,v6.2.0开始被视为废弃,可以用命令GEOSEARCH替代
  • 时间复杂度: O(N+log(M)),其中N为指定范围内(由给定位置和半径构成的圆形区域)的元素数量,M为索引的项目数
  • 解释: 此命令与GEORADIUS一样,以某个点为中心,匹配指定半径区域内的位置。与GEORADIUS唯一不同的是,此命令以名称的方式来提供中心点,而GEORADIUS是通过提供经纬度的方式来决定中心点。
  • 返回值: 参考GEORADIUS命令

GEORADIUSBYMEMBER_RO key member radius M | KM | FT | MI [WITHCOORD] [WITHDIST] [WITHHASH] [ COUNT count [ANY]] [ ASC | DESC]

  • 可用版本: v3.2.10开始,v6.2.0开始被视为废弃,可以用命令GEOSEARCH替代
  • 时间复杂度: O(N+log(M)),其中N为指定范围内(由给定位置和半径构成的圆形区域)的元素数量,M为索引的项目数
  • 解释: 此命令与GEORADIUS_RO一样,以某个点为中心,匹配指定半径区域内的位置。与GEORADIUS_RO唯一不同的是,此命令以名称的方式来提供中心点,而GEORADIUS_RO是通过提供经纬度的方式来决定中心点。
  • 返回值: 参考GEORADIUS_RO命令

GEOSEARCH key FROMMEMBER member | FROMLONLAT longitude latitude BYRADIUS radius M | KM | FT | MI | BYBOX width height M | KM | FT | MI [ ASC | DESC] [ COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH]

  • 可用版本: v6.2.0开始
  • 时间复杂度: O(N+log(M)) 其中 N 是作为过滤器提供的形状周围的网格对齐边界框区域中的元素数,M是形状内的项目数
  • 解释: 此命令扩展于GEORADIUS,同时增加了对矩形区域的支持。
  • 选项说明:
    1. 指定中心点:
      • FROMMEMBER: 以给定名称的位置为中心点
      • FROMLONLAT: 以给定的经纬度为中心点
    2. 指定区域形状:
      • BYRADIUS: 以中心点为圆心,给定半径radius范围内的圆形区域
      • BYBOX: 轴对称的矩形区域,具体范围由heightwidth决定
    3. 返回值内容:
      • WITHDIST: 同时返回匹配项与中心点的距离,距离单位与命令指定的半径单位相同
      • WITHCOORD: 同时返回匹配项的经纬度坐标
      • WITHHASH: 同时返回匹配项的GEOHASH值
    4. 返回匹配项的顺序:
      • ASC: 按照距离中心点由近到远的顺序排序
      • DESC: 按照距离中心距离由远到近的顺序排序
    5. 命令默认返回区域内所有的匹配项,调用方可以通过COUNT参数指定需要返回的匹配项数量,当COUNT参数被提供了ANY参数时,命令将会尽快返回,即只要匹配项个数满足COUNT后立即返回。
  • 返回值: Array(数组)
    • 没有指定WITH选项时,命令仅仅返回由位置名称组成的数组: [“北京”,”上海”,”广州”,深圳”]
    • 如果指定了WITHCORRDWITHDISTWITHHASH选项时,命令返回数组,数组的每个元素代表一个地理位置,其中包括名称、经纬度、距离中心点的距离、GEOHASH值等(具体内容视参数选项而定),作为规定,子数组里每个元素的顺序是固定的,根据指定的参数选项,可能会没有某些值,但整体顺序保持不变(具体视给定的命令参数选项而定):
      1. 位置名称
      2. 与中心点的距离,单位与命令中的半径单位保持一致
      3. 位置的经纬度(经度,纬度)

GEOSEARCHSTORE destination source FROMMEMBER member | FROMLONLAT longitude latitude BYRADIUS radius M | KM | FT | MI | BYBOX width height M | KM | FT | MI [ ASC | DESC] [ COUNT count [ANY]] [STOREDIST]

  • 可用版本: v6.2.0开始
  • 时间复杂度: O(N+log(M)) 其中 N 是作为过滤器提供的形状周围的网格对齐边界框区域中的元素数,M是形状内的项目数
  • 解释: 此命令为GEOSEARCH的存储版本,即命令最后不是将匹配结果返回给客户端,而是存储进给定的目标键中,参数详细介绍可以参考GEOSEARCH命令。默认情况下,会直接将位置信息存储进目标键中,如果给定了STOREDIST选项,那么会以匹配项与中心点的距离作为分数存储进目标键对应的有序集合中。
  • 返回值: Integer(整型),返回存储进目标键中的成员数量

参考资料

Redis GEO