前记apache
这段时间须要修改一个别人写的一个搜索有关的项目,刚好底层使用的是lucene搜索框架。框架
为何要去修改呢,固然是搜索结果不太使人满意啦,因而去研读了项目中关于搜索的代码。。。。。。ide
正文工具
通过了几天代码的研读,最终总结出来了几条问题:this
建立索引的过程,至关简单,感受仅仅是把lucene当成关键词匹配的工具去了(须要修改索引策略)spa
搜索的过程也是比较简单,没有结合项目的需求,定制化搜索(搜索策略须要修改)对象
额,感受上面两条好像是在说废话,感受lucene的和核心就是索引和搜索排序
为了能尽快解决问题,初步修改就定为了:继承
索引阶段,将信息分红多个域,同时根据域的重要程度,加入权重。还有就是加入搜索结果排序要使用的字段(分域,权重,加入排序字段)索引
搜索阶段 根据类别搜索不一样的域,同时加入自定义评分
下面就简单的说一下自定义评分:
我用的是lucene是:
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.10.2</version>
</dependency>
上网查了不少的资料,发现lucene实现自定义评分是经过在构建查询的时候加入的,操做起来很方便。直接上代码吧:
public class MyCustomScoreQuery extends CustomScoreQuery {
public MyCustomScoreQuery(Query subQuery) {
super(subQuery);
}
@Override
protected CustomScoreProvider getCustomScoreProvider(
AtomicReaderContext context) throws IOException {
/**
* 自定义的评分provider
* **/
return new AbilityCoverageScoreProvider(context);
}
private class MyCustomScoreProvider extends CustomScoreProvider {
private AtomicReaderContext context = null;
public MyCustomScoreProvider(AtomicReaderContext context) {
super(context);
this.context = context;
}
@Override
public float customScore(int doc, float subQueryScore, float valSrcScore)
throws IOException {
//获取double型,使用Cache获取更加的快速
FieldCache.Doubles doubles = FieldCache.DEFAULT.getDoubles(context.reader(), "range", false);
double range= doubles.get(doc);
return subQueryScore + range;
}
}
}
总结下来就是:
继承CustomScoreQuery类,覆盖getCustomScoreProvider(AtomicReaderContext context)方法,返回本身的评分对象
继承CustomScoreProvider,覆盖customScore(int doc, float subQueryScore, float valSrcScore)方法,返回评分结果
自定义评分逻辑就是写在customScore(int doc, float subQueryScore, float valSrcScore)里面,事先算好的排序因子,能够当成是域放在document里面,而后在自定义评分的时候取出来,实现自定义评分从而影响排序。
最后就只用使用本身的MyCustomScoreQuery去包装一个query,而后去搜索就好了。
Query query = 生成好的query
Query customQuery = new MyCustomScoreQuery(query);
最后用customQuery去搜索。。。