摘自:http://blog.csdn.net/seven_zhao/article/details/42708953
1.基于FunctionQuery,(1)创建类并继承ValueSource;(2)重写getValues方法。
1 private class MyScore2 extends ValueSource{ 2 3 @Override 4 public FunctionValues getValues(Map context, 5 final AtomicReaderContext readerContext) throws IOException { 6 return new FloatDocValues(this); } 7 8 @Override 9 public float floatVal(int doc) { 10 float s = 1; 11 //从域缓存中读取数据 12 // 从域缓存中加载索引字段信息 13 try { 14 Longs longs= FieldCache.DEFAULT.getLongs(readerContext.reader(), "size", false); 15 long size = longs.get(doc); 16 if(size>1000){ 17 s = 0.5f; 18 } 19 } catch (IOException e) { 20 // TODO Auto-generated catch block 21 e.printStackTrace(); 22 } 23 return s; 24 } 25 } 26 }
2.(1)创建类并继承CustomScoreQuery
(2)覆盖重写类中的getCusomScoreProvider方法
(3)创建类并继承CustomScoreProvider
(4)覆盖重写类中的customScore确定新的评分规则
public class MySelfScore { public void searchBySelfScore(){ try{ IndexSearcher search = new IndexSearcher(DirectoryReader.open(FileIndexUtils.getDirectory())); Query q = new TermQuery(new Term("content","java")); MyCustomScoreQuery myQuery = new MyCustomScoreQuery(q); TopDocs tds = search.search(myQuery, 200); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(ScoreDoc sd:tds.scoreDocs){ Document d = search.doc(sd.doc); System.out.println(sd.doc+":("+sd.score+")" + "["+d.get("filename")+"【"+d.get("path")+"】--->"+ d.get("size")+"-----"+sdf.format(new Date(Long.valueOf(d.get("date"))))+"]"); } System.out.println("-----------Total result:"+tds.scoreDocs.length); }catch(Exception e){ e.printStackTrace(); } } /** *重写评分的实现方式 * **/ private class MyScoreProvider extends CustomScoreProvider{ private AtomicReaderContext context; public MyScoreProvider(AtomicReaderContext context) { super(context); this.context = context; } /**重写评分方法,假定需求为文档size大于1000的评分/1000**/ @Override public float customScore(int doc, float subQueryScore, float valSrcScore) throws IOException { // 从域缓存中加载索引字段信息 Longs longs= FieldCache.DEFAULT.getLongs(context.reader(), "size", false); /**注册使用自定义的评分实现方式**/ // 1. 域值要单一,对于string类型不能分词(NOT_ANALYZED) // 2. 该域需要建入索引(INDEXED) // 3. 支持的数据类型,byte/short/int/long/float/double // weights.get(doc).utf8ToString();获取string值 BinaryDocValues weights = FieldCache.DEFAULT.getTerms(context.reader(), "title", true); if(weights.get(doc).utf8ToString().equals("1")){ System.out.println(doc+" : "+weights.get(doc).utf8ToString()); System.out.println(context.reader().document(doc).get("author")); return subQueryScore * valSrcScore*15; } /* * 通过得分相乘放大分数 * 此处可以控制与原有得分结合的方式,加减乘除都可以 * **/ return subQueryScore*valSrcScore; } } /** * 重写CustomScoreQuery 的getCustomScoreProvider方法 * 引用自定义的Provider */ private class MyCustomScoreQuery extends CustomScoreQuery{ public MyCustomScoreQuery(Query subQuery) { super(subQuery); } @Override protected CustomScoreProvider getCustomScoreProvider( AtomicReaderContext context) throws IOException { return new MyScoreProvider(context); } } }