<< Lucene索引阶段设置Document Boost和Field Boost 实现合理打分 - 漫步天涯-IT - 博客频道 - CSDN.NET | 首页 | BOSS系统_通信百科 >>

lucene实现自定义的评分 - 学习笔记 - 博客频道 - CSDN.NET

Lucene按一个或多个字段进行排序是基本的功能,但可能需要更高级的自定义排序功能,并通过调整得分。Lucene自定义排序调整打分方法,有下面几种:

1、在索引阶段设置Document Boost和Field Boost,提升文档或字段的排名,例如:

Document doc1 = new Document(); 
  Field f1 = new Field("contents", "common hello hello", Field.Store.NO, Field.Index.ANALYZED); 
  doc1.add(f1); 
  doc1.setBoost(100); 
  writer.addDocument(doc1); 

 Document doc1 = new Document(); 
  Field f1 = new Field("title", "common hello hello", Field.Store.NO, Field.Index.ANALYZED); 
  f1.setBoost(100); 
  doc1.add(f1); 
  writer.addDocument(doc1); 

2、通过继承并实现自己的Similarity,覆盖方法float scorePayload(int docId, String fieldName, int start, int end, byte [] payload, int offset, int length)

class PayloadSimilarity extends DefaultSimilarity {

  @Override
  public float scorePayload(int docId, String fieldName, int start, int end, byte[] payload, int offset, int length) {
    int isbold = BoldFilter.bytes2int(payload);
    if(isbold == BoldFilter.IS_BOLD){
      System.out.println("It is a bold char.");
      return 10;
    } else {
      System.out.println("It is not a bold char.");
      return 1;
    }
  }
}

 

3、继承并实现自己的collector

4、继承并实现自定义CustomScoreProvider和CustomScoreQuery,对评分进行干预,影响排名排序,例如:

 

[java] view plaincopy
 
  1. package util;  
  2.   
  3. import java.io.IOException;  
  4. import org.apache.lucene.index.IndexReader;  
  5. import org.apache.lucene.index.Term;  
  6. import org.apache.lucene.search.IndexSearcher;  
  7. import org.apache.lucene.search.Query;  
  8. import org.apache.lucene.search.TermQuery;  
  9. import org.apache.lucene.search.TopDocs;  
  10. import org.apache.lucene.search.function.CustomScoreProvider;  
  11. import org.apache.lucene.search.function.CustomScoreQuery;  
  12. import org.apache.lucene.search.function.FieldScoreQuery;  
  13. import org.apache.lucene.search.function.ValueSourceQuery;  
  14. import org.apache.lucene.search.function.FieldScoreQuery.Type;  
  15.   
  16. public class MyScoreQuery1{  
  17.       
  18.     public void searchByScoreQuery() throws Exception{  
  19.         IndexSearcher searcher = DocUtil.getSearcher();  
  20.         Query query = new TermQuery(new Term("content","java"));  
  21.           
  22.         //1、创建评分域,如果Type是String类型,那么是Type.BYTE  
  23.         //该域必须是数值型的,并且不能使用norms索引,以及每个文档中该域只能由一个语汇  
  24.         //单元,通常可用Field.Index.not_analyzer_no_norms来进行创建索引  
  25.         FieldScoreQuery fieldScoreQuery = new FieldScoreQuery("size",Type.INT);  
  26.         //2、根据评分域和原有的Query创建自定义的Query对象  
  27.         //query是原有的query,fieldScoreQuery是专门做评分的query  
  28.         MyCustomScoreQuery customQuery = new MyCustomScoreQuery(query, fieldScoreQuery);  
  29.           
  30.         TopDocs topdoc = searcher.search(customQuery, 100);  
  31.         DocUtil.printDocument(topdoc, searcher);  
  32.         searcher.close();  
  33.           
  34.     }  
  35.       
  36.     @SuppressWarnings("serial")  
  37.     private class MyCustomScoreQuery extends CustomScoreQuery{  
  38.   
  39.         public MyCustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) {  
  40.             super(subQuery, valSrcQuery);  
  41.         }  
  42.           
  43.         /** 
  44.          * 这里的reader是针对段的,意思是如果索引包含的段不止一个,那么搜索期间会多次调用 
  45.          * 这个方法,强调这点是重要的,因为它使你的评分逻辑能够有效使用段reader来对域缓存 
  46.          * 中的值进行检索 
  47.          */  
  48.         @Override  
  49.         protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)  
  50.                 throws IOException {  
  51.             //默认情况实现的评分是通过原有的评分*传入进来的评分域所获取的评分来确定最终打分的  
  52.             //为了根据不同的需求进行评分,需要自己进行评分的设定  
  53.             /** 
  54.              * 自定评分的步骤 
  55.              * 创建一个类继承于CustomScoreProvider 
  56.              * 覆盖customScore方法 
  57.              */  
  58. //          return super.getCustomScoreProvider(reader);  
  59.             return new MyCustomScoreProvider(reader);  
  60.         }  
  61.           
  62.           
  63.     }  
  64.       
  65.     private class MyCustomScoreProvider extends CustomScoreProvider{  
  66.   
  67.         public MyCustomScoreProvider(IndexReader reader) {  
  68.             super(reader);  
  69.         }  
  70.           
  71.         /** 
  72.          * subQueryScore表示默认文档的打分 
  73.          * valSrcScore表示的评分域的打分 
  74.          * 默认是subQueryScore*valSrcScore返回的 
  75.          */  
  76.         @Override  
  77.         public float customScore(int doc, float subQueryScore, float valSrcScore)throws IOException {  
  78.             System.out.println("Doc:"+doc);  
  79.             System.out.println("subQueryScore:"+subQueryScore);  
  80.             System.out.println("valSrcScore:"+valSrcScore);  
  81. //          return super.customScore(doc, subQueryScore, valSrcScore);  
  82.             return subQueryScore / valSrcScore;  
  83.         }  
  84.           
  85.     }  
  86. }  


根据特定的几个文件名来评分,选中的文件名权重变大

 

 

[java] view plaincopy
 
  1. package util;  
  2.   
  3. import java.io.IOException;  
  4. import org.apache.lucene.index.IndexReader;  
  5. import org.apache.lucene.index.Term;  
  6. import org.apache.lucene.search.FieldCache;  
  7. import org.apache.lucene.search.IndexSearcher;  
  8. import org.apache.lucene.search.Query;  
  9. import org.apache.lucene.search.TermQuery;  
  10. import org.apache.lucene.search.TopDocs;  
  11. import org.apache.lucene.search.function.CustomScoreProvider;  
  12. import org.apache.lucene.search.function.CustomScoreQuery;  
  13. /** 
  14.  * 此类的功能是给特定的文件名加权,也就是加评分 
  15.  * 也可以实现搜索书籍的时候把近一两年的出版的图书给增加权重 
  16.  * @author user 
  17.  */  
  18. public class MyScoreQuery2 {  
  19.     public void searchByFileScoreQuery() throws Exception{  
  20.         IndexSearcher searcher = DocUtil.getSearcher();  
  21.         Query query = new TermQuery(new Term("content","java"));  
  22.           
  23.         FilenameScoreQuery fieldScoreQuery = new FilenameScoreQuery(query);  
  24.           
  25.         TopDocs topdoc = searcher.search(fieldScoreQuery, 100);  
  26.         DocUtil.printDocument(topdoc, searcher);  
  27.         searcher.close();  
  28.           
  29.     }  
  30.       
  31.     @SuppressWarnings("serial")  
  32.     private class FilenameScoreQuery extends CustomScoreQuery{  
  33.   
  34.         public FilenameScoreQuery(Query subQuery) {  
  35.             super(subQuery);  
  36.         }  
  37.   
  38.         @Override  
  39.         protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)  
  40.                 throws IOException {  
  41. //          return super.getCustomScoreProvider(reader);  
  42.             return new FilenameScoreProvider(reader);  
  43.         }  
  44.     }  
  45.       
  46.     private class FilenameScoreProvider extends CustomScoreProvider{  
  47.         String[] filenames = null;  
  48.         public FilenameScoreProvider(IndexReader reader) {  
  49.             super(reader);  
  50.             try {  
  51.                 filenames = FieldCache.DEFAULT.getStrings(reader, "filename");  
  52.             } catch (IOException e) {e.printStackTrace();}  
  53.         }  
  54.   
  55.         //如何根据doc获取相应的field的值  
  56.         /* 
  57.          * 在reader没有关闭之前,所有的数据会存储要一个域缓存中,可以通过域缓存获取很多有用 
  58.          * 的信息filenames = FieldCache.DEFAULT.getStrings(reader, "filename");可以获取 
  59.          * 所有的filename域的信息 
  60.          */  
  61.         @Override  
  62.         public float customScore(int doc, float subQueryScore, float valSrcScore)  
  63.                 throws IOException {  
  64.             String fileName = filenames[doc];  
  65.             System.out.println(doc+":"+fileName);  
  66. //          return super.customScore(doc, subQueryScore, valSrcScore);  
  67.             if("9.txt".equals(fileName) || "4.txt".equals(fileName)) {  
  68.                 return subQueryScore*1.5f;  
  69.             }  
  70.             return subQueryScore/1.5f;  
  71.         }  
  72.           
  73.     }  
  74. }  
  75.  

 

 

阅读全文……

标签 : , ,



发表评论 发送引用通报