基于Solr空间搜索

概括:

     最近一个项目需要基于LBS查询附近的商铺信息,看了一下网上都是基于Solr和ELS方式来实现, 本来想使用ELS来实现的,但是由于项目以前用的是Solr, 所以就去调研了一下基于Solr来实现地理位置的搜索,并且在实现的时候整理了一下实现的笔记。       

    在开发中如果需要对带经纬度的数据进行检索,比如查找当前所在位置附近1000米的,一种简单的方法就是:获取数据库中的所有酒店数据,按经纬度计算距离,返回距离小于1000米的数据。

   这种方式在数据量小的时候比较有效,但是当数据量大的时候,检索的效率是会十分十分低的,本文介绍使用Solr的Spatial Query进行空间搜索。本文简述基于Solr实现空间范围搜索

基于Mysql 实现地理位置排序:

例如:

公式如下,单位米:

第一点经纬度:lng1 lat1

第二点经纬度:lng2 lat2

      round(6378.138*2*asin(sqrt(pow(sin( (lat1*pi()/180-lat2*pi()/180)/2),2)+cos(lat1*pi()/180)*cos(lat2*pi()/180)* pow(sin( (lng1*pi()/180-lng2*pi()/180)/2),2)))*1000) 

例如:

    SELECT    store_id,lng,lat, ROUND(6378.138*2*ASIN(SQRT(POW(SIN((22.299439*PI()/180-      lat*PI()/180)/2),2)+COS(22.299439*PI()/180)*COS(lat*PI()/180)*POW(SIN((114.173881*PI()/180-lng*PI()/180)/2),2)))*1000) AS juli  FROM store_info

ORDER BY juli DESC
LIMIT 316

基于Solr实现地理位置排序:

没学过的Solr 这里有一份官网手册: 

 http://lucene.apache.org/solr/guide/6_6/spatial-search.html


原理:

   具体的空间搜索原理和算法不多介绍,空间搜索算法都是很成熟的

     https://www.cnblogs.com/hanhuibing/articles/5680616.html

    https://www.cnblogs.com/keleyu/p/4993039.html

基于Solr的空间搜索实战:

   Solr已经提供了3种filedType来进行空间搜索:

  有四种可用于空间搜索的主要字段类型:

LatLonPointSpatialField

LatLonType (现已弃用)及其非大地双胞胎 PointType

SpatialRecursivePrefixTreeFieldType(简称RPT),包括RptWithGeometrySpatialField衍生产品

BBoxField


LatLonPointSpatialField是经纬度点数据最常见使用情况的理想字段类型。它取代了为了向后兼容而仍然存在的LatLonType。RPT提供了更多高级/自定义用例以及诸如多边形和热图等选项的更多功能。

RptWithGeometrySpatialField用于索引和搜索非点数据,尽管它也可以做点。它不能做排序/提升。

BBoxField 用于索引边界框,通过框查询,指定搜索谓词(相交,内部,包含,不相交,等于)以及相关性排序/提升类似overlapRatio或简单区域。

LatLonPointSpatialField  

  <fieldType name="location" class="solr.LatLonPointSpatialField" docValues="true"/>

   Indexing Points使用(x y) 或者(lat,lon) 格式进行保存;不然会报错

image.png

   用于地理空间搜索的空间Solr“查询分析器”:geofilt和bbox

geofilt

    该geofilt过滤器允许您根据给定点的地理空间距离(也称为“大圆距离”)检索结果。另一种看待它的方式是创建一个圆形滤镜。例如,要查找给定纬度/经度点五公里内的所有文件,可以输入。该过滤器返回给定半径的圆周内的所有结果:

   &q=:&fq={!geofilt sfield=store}&pt=45.15,-93.85&d=5

   image.png


bbox

该bbox过滤器与geofilt使用计算的圆的边界框非常相似。请参阅下图中的蓝色框。它采用与geofilt相同的参数。

以下是一个示例查询:

  &q=:&fq={!bbox sfield=store}&pt=45.15,-93.85&d=5


 矩形形状的计算速度更快,所以它有时可以用来替代geofilt返回半径之外的点的可接受范围。但是,如果理想目标是一个圆圈,但您希望它运行得更快,那么请考虑使用RPT字段并尝试一个较大的distErrPct值0.1(如10%半径)。这将返回半径之外的结果,但它将在形状周围有点均匀。

image.png

   当边界框包含一个极点时,边界框最终成为一个“边界盆”(球冠),如果边界框接触北极(或最高纬度的南部,如果有),则该边界包括圆的最低纬度以北的所有值它接触南极)。

通过任意矩形进行过滤

     有时,空间搜索要求要求在矩形区域中查找所有内容,例如用户正在查看的地图所覆盖的区域。对于这种情况,geofilt和bbox不会剪切它。这是一个窍门,但是你可以使用Solr的范围查询语法来提供左下角作为范围的开始和右上角作为范围的结束。

这是一个例子:

   &q=:&fq=store:[45,-94 TO 46,-93]

优化:缓存与否

将空间查询放入“fq”参数中是最常见的过滤器查询。默认情况下&#x

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值