Lucene自定义评分查询
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(); }