/** * 自定义评分流程: * 1.创建一个评分域 * 2.根据原有Query(termQuery)和评分域Query(scoreQuery)创建自定义的MyCustomScoreQuery对象 * 2.1创建自定义的MyCustomScoreQuery对象 * 2.2重载“getCustomScoreProvider()”方法 * 3.自定义评分步骤: * 3.1自定义类继承自CustomScoreProvider * 3.2重载customScore()方法 */ public class MyScoreQuery { public void searchByScoreQuery(){ IndexSearcher indexSearcher = null; try { indexSearcher = new IndexSearcher(IndexReader.open(FileIndexUtil.getDirectory())); TermQuery termQuery = new TermQuery(new Term("filename", "公主")); //1.创建一个评分域 /** * 创建一个评分域:FieldScoreQuery * FieldScoreQuery(String field, Type type) * 参数一:域名 * 参数二:type 类型 * FieldScoreQuery.Type.INT 域值是整型 * FieldScoreQuery.Type.BYTE 域值是字符串 */ FieldScoreQuery scoreQuery = new FieldScoreQuery("score", FieldScoreQuery.Type.INT); //2.根据原有Query(termQuery)和评分域Query(scoreQuery)创建自定义的MyCustomScoreQuery对象 MyCustomScoreQuery myCustomScoreQuery = new MyCustomScoreQuery(termQuery, scoreQuery); searchByQuery(indexSearcher, myCustomScoreQuery); } catch (IOException e) { e.printStackTrace(); } finally { if (indexSearcher != null){ try { indexSearcher.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 2.1创建自定义类继承自“CustomScoreQuery” */ private class MyCustomScoreQuery extends CustomScoreQuery{ /** * 自定义类继承CustomScoreQuery,需要添加构造函数,共有三种: * 第一种:CustomScoreQuery(Query subQuery) * 第一种只传入“原有Query”,即默认评分规则 * 第二种:CustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) * 第二种传入“原有Query”和“自定义的评分域Query”,即加入自定义评分规则 * 第三种:CustomScoreQuery(Query subQuery, ValueSourceQuery... valSrcQueries) * 第二种传入“原有Query”和多个“自定义的评分域Query”,即加入多个自定义评分规则 * 可以实现: * 搜索文件标题含有“公主”的文件,同时按照文件修改时间由近到远的排序,同时按照 * 文件大小由小到大排序 */ /** * @param subQuery 原有Query(termQuery) * @param valSrcQuery 评分域Query(scoreQuery) */ public MyCustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) { super(subQuery, valSrcQuery); } /** * 2.2重载“getCustomScoreProvider()”方法 * 其中,super.getCustomScoreProvider(reader)是默认评分规则,即: * 原有评分*传进来的评分域 * 为根据不同的需求进行评分,需要自己进行评分的设定,即自定义类继承CustomScoreProvider */ @Override protected CustomScoreProvider getCustomScoreProvider(IndexReader reader) throws IOException { // return new MyCustomScoreProvider(reader); return new FileNameCustomScoreProvider(reader); } } /** * 3.自定义评分步骤: * 3.1自定义类继承自CustomScoreProvider * 3.2重载customScore()方法 */ /** * 3.1自定义类继承自CustomScoreProvider */ private class MyCustomScoreProvider extends CustomScoreProvider{ public MyCustomScoreProvider(IndexReader reader) { super(reader); } //3.2重载customScore()方法 /** * 若只传入一个评分域,则需要重载customScore(int doc, float subQueryScore, float valSrcScore)方法 * 若传入多个评分域,则需要重载customScore(int doc, float subQueryScore, float[] valSrcScore)方法 * 参数subQueryScore:默认文档评分 * 参数valSrcScore: 传入评分域评分 */ @Override public float customScore(int doc, float subQueryScore, float valSrcScore) throws IOException { return subQueryScore/valSrcScore; } } /** * 练习:对原有搜索出来的排序结果再进行优化,“.txt”和“.ini文件在前”,其他按照原有的排序 */ private class FileNameCustomScoreProvider extends CustomScoreProvider{ String[] fileNames = null; public FileNameCustomScoreProvider(IndexReader reader) { super(reader); try { /** * 在IndexReader没有关闭之前,所有的数据都会存储在一个缓存域中,可以通过缓存域获取域值(前提是该域存储起来了) * FieldCache.DEFAULT.getStrings(reader, "filename") */ fileNames = FieldCache.DEFAULT.getStrings(reader, "filename"); } catch (IOException e) { e.printStackTrace(); } } @Override public float customScore(int doc, float subQueryScore, float valSrcScore) throws IOException { /** * 如何通过doc获取相应的filed值? * 在IndexReader没有关闭之前,所有的数据都会存储在一个缓存域中,可以通过缓存域获取域值(前提是该域存储起来了) * FieldCache.DEFAULT.getStrings(reader, "filename") */ String fileName = fileNames[doc]; //文件名被我分词了,找不到了 if (fileName != null && (fileName.endsWith(".txt") || fileName.endsWith(".ini"))){ //若文件是".txt"或".ini"文件,加评分 return subQueryScore*valSrcScore*10; } return subQueryScore*valSrcScore; } } public void searchByQuery(IndexSearcher indexSearcher, Query termQuery) throws IOException { TopDocs topDocs = indexSearcher.search(termQuery, 100); ScoreDoc[] scoreDocs = topDocs.scoreDocs; if (!CollectionUtil.isEmpty(scoreDocs)){ for (ScoreDoc scoreDoc:scoreDocs){ Document document = indexSearcher.doc(scoreDoc.doc); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm"); System.out.println(scoreDoc.doc+"["+scoreDoc.score+"]---->["+ "["+document.get("filename")+"]---->[" +simpleDateFormat.format(new Date(Long.valueOf(document.get("time"))))+"]---->[" +document.get("size")+"]"); } } } }
18、学习Lucene3.5索引之自定义评分
最新推荐文章于 2018-09-17 15:41:00 发布