记Lucene GEO Query的一点优化

45 篇文章 0 订阅
20 篇文章 0 订阅

目前我们使用的是Lucene 4.0,上面对GEO query的使用是这样的,索引阶段使用geo hash索引多个级别的geo grid,检索阶段获取geo grid做termquery,or起来,最后search之后在collector中按照距离做一次手动的过滤,这样做不方便的是geo query不能任意和其他query做or组合。

又查看了lucene spatial中的实现,是直接确定精度之后做索引,索引可能较快了,但是检索阶段需要使用PrefixQuery,感觉上灵活性较差,需要遍历每个最小的grid(具体仍需测试和权衡),检索阶段Geo Query是FilteredQuery(MatchAllDocsQuery, GEOFilter),GEO filter实际上主要接口是getDocIdSet(所以solr中很多filter是要缓存的),这样geo query是可以和其他query任意组合的。

我也按照这个思路写了个geo filter,实测一下发现比之前的性能有很大提高。

在我本机上做了一些简单测试,结果上用新的方式优于老的geo query(相关代码我提交在arts的test_geo_ filter分支了)。索引上海所有上海, 3000个附近搜索请求,不带任何关键字,结果如下:

1公里 老geo需要15.54秒, 新的7.32秒;
2公里 老geo需要31.41秒,新的13.71秒;
5公里 老geo需要65.71秒,新的34.85秒;
20公里 老geo需要91.50秒,新的48.75秒。

代码读下来,之所以提高有两处:

1.Collector中acceptDocsOutOfOrder()返回false,这样从不同term query返回的dicid每次需要在堆中选择一下;

2.对应的Term Query做了打分操作(DisconjunctionSumScorer),但实际scorer其实是在collector中完成,这样就浪费了。

另外发现query有个rewrite方法,可以对查询做优化,对于连续的And操作,有Conjunction Query做优化。

使用FilteredQuery经rewrite之后变成ConstantScoreQuery,没什么overhead。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值