這里我們是工程lucene_analyzer04
- 1.自定義評分思路
- 創(chuàng)建一個(gè)類繼承于
CustomScoreQuery
- 覆蓋里面的方法
getCustomScoreProvider()
- 創(chuàng)建一個(gè)類
CustomScoreProvider
- 覆蓋
CustomScoreProvider中的方法customScore()
,在這個(gè)方法中創(chuàng)建評分規(guī)則纸淮。
- 創(chuàng)建一個(gè)類繼承于
- 2.首先看一個(gè)示例
我們在FileIndexUtil.java
中定義一個(gè)隨機(jī)數(shù)平斩,這個(gè)隨機(jī)數(shù)作為一個(gè)評分。
// 創(chuàng)建索引
public static void index(boolean hasNew) {
IndexWriter writer = null;
try {
writer = new IndexWriter(directory, new IndexWriterConfig(
Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
if (hasNew) {
writer.deleteAll();//如果我們要新建索引萎馅,那么將之前創(chuàng)建的刪除
}
File file = new File("E:/myeclipse/Lucene/somefile");
Document document = null;
Random random = new Random();
for (File f : file.listFiles()) {
//將每個(gè)索引的評分設(shè)置成一個(gè)隨機(jī)數(shù)
int score = random.nextInt(600);
document = new Document();
document.add(new Field("content", new FileReader(f)));
document.add(new Field("filename", f.getName(),
Field.Store.YES, Field.Index.NOT_ANALYZED));
document.add(new Field("path", f.getAbsolutePath(),
Field.Store.YES, Field.Index.NOT_ANALYZED));
document.add(new NumericField("date", Field.Store.YES, true)
.setLongValue(f.lastModified()));
// 最后我們將字節(jié)數(shù)轉(zhuǎn)換成kb
document.add(new NumericField("size", Field.Store.YES, true)
.setIntValue((int) (f.length())));
//這里我們使用score評分來創(chuàng)建索引双戳,沒有存儲,搜索出來的時(shí)候?yàn)閚ull
//這里我自己隨機(jī)設(shè)置的一個(gè)評分
document.add(new NumericField("score", Field.Store.NO, true).setIntValue(score));
writer.addDocument(document);
}
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (LockObtainFailedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
說明:定義隨機(jī)評分之后再次生成索引糜芳。
- 3.自定義評分規(guī)則
MyScoreQuery.java
public void searchByScoreQuery(){
try {
IndexSearcher searcher = new IndexSearcher(IndexReader.open(FileIndexUtil.getDirectory()));
Query q = new TermQuery(new Term("content", "json"));
//1、創(chuàng)建一個(gè)評分域
FieldScoreQuery fsq = new FieldScoreQuery("score", Type.INT);//如果是字符串選擇BYTE類型魄衅,這里是int類型
//2峭竣、根據(jù)評分域和原有的Query創(chuàng)建自定義的Query對象
MyCustomScoreQuery query = new MyCustomScoreQuery(q, fsq);
TopDocs tds = null;
tds = searcher.search(query, 20);//使用自定義的query
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (ScoreDoc sd : tds.scoreDocs) {
Document doc = searcher.doc(sd.doc);
System.out.println("id:" + sd.doc + ",評分:" + sd.score
+ "晃虫,名稱:" + doc.get("filename") + "皆撩,路徑:" + doc.get("path")
+ ",文件大姓芤:" + doc.get("size") + "扛吞,日期:"
+ sdf.format(new Date(Long.valueOf(doc.get("date")))));
}
searcher.close();
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private class MyCustomScoreQuery extends CustomScoreQuery{
//subQuery表示原有的Query,valSrcQuery用于做評分的Query
//CustomScoreQuery其實(shí)有很多構(gòu)造方法荆责,我們可以一次性傳入很多評分規(guī)則
public MyCustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) {
super(subQuery, valSrcQuery);
}
//3滥比、覆蓋此方法
@Override
protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)
throws IOException {
//默認(rèn)情況實(shí)現(xiàn)的評分是通過 原有的評分*傳入 進(jìn)來的評分域得到最后的評分
//而這種評分算法很顯然是滿足不了我們的要求的,于是我們自己為了根據(jù)不同的需求需要
//自己進(jìn)行評分設(shè)定
/*
* 自定義評分的步驟
* (1)創(chuàng)建一個(gè)類繼承于CustomScoreProvider
* (2)覆蓋CustomScoreProvider中的方法customScore()
* */
return new MyCustomScoreProvider(reader);
}
}
private class MyCustomScoreProvider extends CustomScoreProvider{
public MyCustomScoreProvider(IndexReader reader) {
super(reader);
}
//此方法中subQueryScore表示默認(rèn)文檔的打分做院,valSrcScore表示的是評分域的打分
@Override
public float customScore(int doc, float subQueryScore, float valSrcScore)
throws IOException {
//這是按評分的降序排盲泛,之前默認(rèn)的是subQueryScore * valSrcScore
return subQueryScore / valSrcScore;
}
}
說明:
- 1.這里我們是利用之前創(chuàng)建的那個(gè)隨機(jī)評分,首先當(dāng)然是創(chuàng)建評分域
FieldScoreQuery
键耕,這里我們選擇的是score
域寺滚。然后是根據(jù)評分域和原有的Query
創(chuàng)建自定義的Query
對象。
自定義的Query
對象MyCustomScoreQuery
必須繼承CustomScoreQuery
對象屈雄,然后需要一個(gè)構(gòu)造方法村视,同時(shí)覆寫getCustomScoreProvider
方法,當(dāng)然此方法中我們需要自定義評分規(guī)則類MyCustomScoreProvider
酒奶,此類需要繼承CustomScoreProvider
蚁孔,也是需要一個(gè)構(gòu)造方法,同時(shí)覆寫customScore
方法讥蟆,而我們真正的自定義評分規(guī)則就在這個(gè)方法中定義勒虾。