两个重要的类:CustomScoreQuery和CustomScoreProvider
两个重要的方法:
1:CustomScoreQuery--CustomScoreProvider getCustomScoreProvider(IndexReader reader)
2:CustomScoreProvider----customScore(int doc, float subQueryScore, float valSrcScore)
自定义查询:
public class MyCustoomScoreQuery extends CustomScoreQuery { public MyCustoomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) { super(subQuery, valSrcQuery); } @Override protected CustomScoreProvider getCustomScoreProvider(IndexReader reader) throws IOException { // return super.getCustomScoreProvider(reader); return new MyCustomScoreProvider(reader); } }
自定义评分方式:
public class MyCustomScoreProvider extends CustomScoreProvider { public MyCustomScoreProvider(IndexReader reader) { super(reader); // TODO Auto-generated constructor stub } /* * (non-Javadoc) * @see org.apache.lucene.search.function.CustomScoreProvider#customScore(int, float, float) * @subQueryScore:文档评分 * @valSrcScore :评分域评分 */ @Override public float customScore(int doc, float subQueryScore, float valSrcScore) throws IOException { // TODO Auto-generated method stub //3种方式比较. // return super.customScore(doc, subQueryScore, valSrcScore); // return 1/(subQueryScore*valSrcScore); return valSrcScore; } }
索引创建和搜索:
public void createIndex() { try { directory=FSDirectory.open(new File("D:/lucene/index04")); writer=new IndexWriter (directory, new IndexWriterConfig(Version.LUCENE_36,new StandardAnalyzer(Version.LUCENE_36))); File[] files=new File("D:/src").listFiles(); Random random=new Random(); for(int i=0;i<files.length;i++) { int score=random.nextInt(100); File file=files[i]; Document doc=new Document(); doc.add(new Field("filename", file.getName(),Store.YES,Index.ANALYZED_NO_NORMS)); FileInputStream fis=new FileInputStream(file); doc.add(new Field("contents", new BufferedReader(new InputStreamReader(fis, "UTF-8")))); doc.add(new NumericField("size", Store.YES,true).setLongValue(file.length())); doc.add(new NumericField("score", Store.YES, true).setIntValue(score)); System.out.print(file.length()+" : "); System.out.println("lucene crate index"+i+"from"+file.getAbsolutePath() +"| score: "+score); writer.addDocument(doc); writer.commit(); fis.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(writer!=null) { try { writer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } writer=null; } } } public void search(String string,Query query) { try { directory=FSDirectory.open(new File("D:/lucene/index04")); reader= IndexReader.open(directory); searcher=new IndexSearcher(reader); ScoreDoc[] sds = searcher.search(query,100).scoreDocs; System.out.println("找到了"+sds.length+"篇文章"); for(ScoreDoc doc:sds){ Document document=searcher.doc(doc.doc); System.out.println(document.get("score")+" | "+document.get("filename")); } searcher.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(reader!=null) try { reader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
测试类:
public class ScoreTest { private ScoreUtil scoreUtil=null; @Before public void beforeTest() { scoreUtil=new ScoreUtil(); } @Test public void createIndexTest() { scoreUtil.createIndex(); } @Test public void searchScoreTest() { Query query=new TermQuery(new Term("contents","lucene")); FieldScoreQuery fieldScoreQuery=new FieldScoreQuery("score", FieldScoreQuery.Type.INT); CustomScoreQuery customScoreQuery=new MyCustoomScoreQuery(query,fieldScoreQuery); scoreUtil.search("lucene", customScoreQuery); } }
3种方式的结果(按顺序):
找到了7篇文章 58 | action.txt 45 | shuxue.txt 62 | lucene.txt 75 | jsp.txt 27 | english.txt 22 | struts2.txt 22 | cpp.txt 找到了7篇文章 22 | cpp.txt 22 | struts2.txt 27 | english.txt 75 | jsp.txt 62 | lucene.txt 45 | shuxue.txt 58 | action.txt 找到了7篇文章 75 | jsp.txt 62 | lucene.txt 58 | action.txt 45 | shuxue.txt 27 | english.txt 22 | cpp.txt 22 | struts2.txt