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
原文链接

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容