GeoQuery(二)(Lucene 8.8.0)

  在上一篇文章GeoQuery(一)中,我们基于下面的例子介绍了在GeoHash编码在Elasticsearch中的部分实现,我们继续介绍其剩余内容。

base32编码

  在前面的步骤中,先将经纬度的值量化为两个int类型的数值,随后在交叉编码后,将两个int类型的数值用一个long类型的表示。为了便于介绍,我们称这个long类型的值为interleave。最后,interleave在经过base32编码后,我们就能获得GeoHash编码值。

  同样的我们根据Elasticsearch中的源码来介绍其过程。由于在es中地理位置的精度等级为12(Geohash类中的PRECISION变量定义,如图1所示),加上base32核心处理方式是将5个bit用一个字符(char)描述,故意味着interleave的高60个bit是有效的,同时低4个bit可以用来描述其精度值。

图1:

低4个bit

  上一篇文章中我们获得的interleave的值如下所示:

图2:

  当低4个bit用来描述精度12(0b1100)后,interleave的值如下所示:

图3:

高60个bit

  接着就可以对高60个bit进行base32编码了。总体流程为从这60个bit的末尾开始,每次取出5个bit,其对应的十进制值作为编码表的下标值,在编码表中找到对应的字符,最终生成一个包含12个字符的字符串。如下所示:

图4:

  从图4中可以看出,我们首先取出5个bit,以10110为例,它对应的十进制的值为22,随后将22作为编码表BASE_32的下标值,取出数组元素q,把该值写入到GeoHash编码中。为了图片的整洁性,故图4中只描述了将60个bit的末尾15个bit进行编码的过程。当所有的bit都处理结束后,其最终的GeoHash编码如下所示:

图5:

为什么介绍GeoHash编码

  在Elasticsearch的文档中我们可以知道,以geo_bounding_box query为例,它支持提供GeoHash编码跟经纬度进行地理位置查询,如下所示:

图6:

结语

  下一篇文章将正式开始介绍Elasticsearch中提供的Geo Queries。

点击下载附件