基于Solr的空间搜索(2)
本文将继续围绕Solr+Lucene使用Cartesian Tiers 笛卡尔层和GeoHash的构建索引和查询的细节进行介绍
在Solr中其实支持很多默认距离函数,但是基于坐标构建索引和查询的主要会基于2种方案:
(1)GeoHash
(2)Cartesian Tiers+GeoHash
而这块的源码实现都在lucene-spatial.jar中可以找到。接下来我将根据这2种方案展开关于构建索引和查询细节进行阐述,都是代码分析,感兴趣的看官可以继续往下看。GeoHash
构建索引阶段
定义geohash域,在schema.xml中定义:
<fieldtype name=“geohash” class=“solr.GeoHashField”/>
接下来再构建索引的时候使用到lucene-spatial.jar的GeoHashUtils类:
String geoHash = GeoHashUtils.encode(latitude, longitude);//通过geoHash算法将经纬度变成base32的编码document.addField(“geohash”, geoHash); //将经纬度对应的bash32编码存入索引。
查询阶段
在solrconfig.xml中配置好QP,该QP将对用户的请求Query进行QParser,
查询语法规范是{!spatial sfield=geofield pt= latitude, longitude d=xx, sphere_radius=xx }
sfield:geohash对应的域名
pt:经纬度字符串
d=球面距离
sphere_radius:圆周半径
接下来看看QP是如何解析上述查询语句,然后生成基于GeoHash的Query的,见如下代码,代码来源SpatialFilterQParser的parse()方法:
从源码中可以看到代码作者有标示TODO:optimize this,笔者从源码中看到这块的实现,也觉得确实有疑惑,整个大体实现流程是基于Lucene的Filter的方式来过滤命中docId,但是其过滤的范围让笔者看起来觉得性能会出现问题,可能也是源码中有TODO:optimize this的缘故吧。
接下来继续讲下核心处理流程,Lucene的查询规则是Query->Weight->Scorer,而主要负责查询遍历结果集合的就是Scorer,该例子也不例外,同样是SolrConstantScoreQueryà ConstantWeightà ConstantScorer,通过Query生成Weight,Weight生成Scorer,熟悉Lucene的读者应该很清楚了,这里不再累述,其中ConstantScorer的通过docIdSetIterator遍历获取满足条件的docId。而docIdSetIterator便是前面源码中的ValueSourceRangeFilter,该Filter将会过滤掉不在一个指定球面距离范围内的数据,而ValueSourceRangeFilter并不是实际工作的类,它又将过滤交给了GeohashHaversineFunction,见ValueSourceRangeFilter如下代码:
那么继续看GeohashHaversineFunction,首先看其 getRangeScorer()方法,最核心的部分为:
所以整个查询流程是将索引中的所有docId从第一个docId =0开始,对应的经度纬度和查询经纬度的球面距离是否在查询给定的distance之内,满足着将该docId返回,不满足则过滤。
大家可能看到是所有docId,这也是笔者觉得该过滤范围实现不靠谱的地方,也许是作者说需要进一步优化的地方。大家如果对怎么是所有docId进行过滤有疑惑,可以查看ValueSourceScorer的nextDoc() advance()方法,相信看过之后就明白了。到此Solr基于GeoHash的查询实现介绍完毕了。
建议继续学习:
- 怎样用好Google进行搜索 (阅读:14875)
- 淘宝搜索:定向抓取网页技术漫谈 (阅读:8327)
- 简析搜索引擎中网络爬虫的搜索策略 (阅读:6102)
- 几种常见的基于Lucene的开源搜索解决方案对比 (阅读:4747)
- 用Sphinx快速搭建站内搜索功能 (阅读:4518)
- 基于用户行为分析的搜索引擎自动性能评价 (阅读:4537)
- 互联网网站的反爬虫策略浅析 (阅读:4237)
- 附近地点搜索初探 (阅读:4242)
- Xapian搜索体系结构 (阅读:4138)
- 百度搜索URL参数解析 (阅读:4214)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:hongzhen 来源: 淘宝网综合业务平台团队博客
- 标签: Solr 搜索 空间搜索
- 发布时间:2013-08-15 13:39:11
-
[61] ABTest 平台设计 - 如何进行流量分桶
-
[47] 如何拿下简短的域名
-
[44] 图书馆的世界纪录
-
[43] android 开发入门
-
[42] 【社会化设计】自我(self)部分――欢迎区
-
[42] Oracle MTS模式下 进程地址与会话信
-
[41] 流程管理与用户研究
-
[41] Twitter/微博客的学习摘要
-
[40] WEB系统需要关注的一些点
-
[40] Go Reflect 性能