前記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去搜索。。。