1 package com.lucene.score;
2
3 import java.io.IOException;
4 import java.sql.Date;
5 import java.text.SimpleDateFormat;
6
7 import org.apache.lucene.document.Document;
8 import org.apache.lucene.index.CorruptIndexException;
9 import org.apache.lucene.index.IndexReader;
10 import org.apache.lucene.index.Term;
11 import org.apache.lucene.search.FieldCache;
12 import org.apache.lucene.search.IndexSearcher;
13 import org.apache.lucene.search.Query;
14 import org.apache.lucene.search.ScoreDoc;
15 import org.apache.lucene.search.TermQuery;
16 import org.apache.lucene.search.TopDocs;
17 import org.apache.lucene.search.function.CustomScoreProvider;
18 import org.apache.lucene.search.function.CustomScoreQuery;
19 import org.apache.lucene.search.function.FieldScoreQuery;
20 import org.apache.lucene.search.function.FieldScoreQuery.Type;
21 import org.apache.lucene.search.function.ValueSourceQuery;
22
23 import com.lucene.search.IndexUtils;
24
25 public class MyCustomScore {
26 public void searchByScoreQuery() {
27 try {
28 IndexSearcher searcher = new IndexSearcher(
29 IndexReader.open(IndexUtils.getDirectory()));
30 Query q = new TermQuery(new Term("content", "1"));
31 // 1.创建评分域
32 FieldScoreQuery fieldScoreQuery = new FieldScoreQuery("size",
33 Type.INT);
34 // 2.根据评分域和原有的query创建自定义的query对象
35 // 2.1 创建MyCustomScoreQuery继承CustomScoreQuery
36 // 2.2重写getCustomScoreProvider方法
37 // 2.3创建MyCustomScoreProvider继承CustomScoreProvider
38 // 2.4重写customScore方法,自定义评分算法
39 MyCustomScoreQuery query = new MyCustomScoreQuery(q,
40 fieldScoreQuery);
41 TopDocs docs=searcher.search(query, 30);
42 // 输出信息
43 ScoreDoc[] sds = docs.scoreDocs;
44 Document d = null;
45 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
46 for (ScoreDoc s : sds) {
47 d = searcher.doc(s.doc);
48 System.out.println(s.doc + "->" + s.score + "->"
49 + d.get("filename") + "->" + d.get("size") + "->"
50 + sdf.format(new Date(Long.valueOf(d.get("date")))));
51 }
52
53 } catch (CorruptIndexException e) {
54 e.printStackTrace();
55 } catch (IOException e) {
56 e.printStackTrace();
57 }
58 }
59 }
60
61 @SuppressWarnings("serial")
62 class MyCustomScoreQuery extends CustomScoreQuery {
63
64 public MyCustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) {
65 super(subQuery, valSrcQuery);
66 }
67
68 @Override
69 protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)
70 throws IOException {
71 // 默认情况评分是根据原有的评分*传入进来的评分
72 //return super.getCustomScoreProvider(reader);
73
74 return new MyCustomScoreProvider(reader);
75 }
76 }
77
78 class MyCustomScoreProvider extends CustomScoreProvider {
79
80 String[] filenames = null;
81
82 public MyCustomScoreProvider(IndexReader reader) {
83 super(reader);
84 try {
85 filenames = FieldCache.DEFAULT.getStrings(reader, "filename");
86 } catch (IOException e) {
87 e.printStackTrace();
88 }
89 }
90
91 @Override
92 public float customScore(int doc, float subQueryScore, float valSrcScore)
93 throws IOException {
94 // 根据doc获取文件名
95 String filename = filenames[doc];
96 //判断文件后缀是否为txt结尾,是把评分*10 否则/10
97 if (filename.endsWith(".txt")) {
98 return subQueryScore * 10;
99 } else {
100 return subQueryScore / 10;
101 }
102 }
103 }
@Test
public void test01(){
MyCustomScore score=new MyCustomScore();
score.searchByScoreQuery();
}