步骤
- 第一步:创建类并继承自CustomScoreQuery
- 第二步:实现类的相应的构造函数
- 第三步:重写getCustomScoreProvider()方法
- 第四步:创建类并继承自CustomScoreProvider
- 第五步:实现自定义类的构造函数
- 第六步:重写getCustomScore()方法
【示例】
1 /** 2 * 自定义评分查询器 3 * @author Terry 4 * 5 */ 6 public class BookScoreQuery extends CustomScoreQuery{ 7 8 /** 9 * 实现相应的构造函数 10 * @param subQuery 11 */ 12 public BookScoreQuery(Query subQuery) { 13 super(subQuery); 14 System.out.println("yes"); 15 } 16 17 /** 18 * 实现getCustomScoreProvider()方法 19 */ 20 @Override 21 protected CustomScoreProvider getCustomScoreProvider(IndexReader reader) 22 throws IOException { 23 // TODO Auto-generated method stub 24 //return super.getCustomScoreProvider(reader); 25 return new BookScoreProvider(reader); 26 } 27 }
1 /** 2 * 实现自定义评分 3 * @author Terry 4 * 5 */ 6 public class BookScoreProvider extends CustomScoreProvider{ 7 8 public BookScoreProvider(IndexReader reader) { 9 super(reader); 10 } 11 12 /** 13 * 自定义评分 14 * 参数1:文档的索引Id 15 * 参数2:文档的评分 16 * 参数3:其他评分域 17 */ 18 @Override 19 public float customScore(int doc, float subQueryScore, float valSrcScore) 20 throws IOException { 21 //return super.customScore(doc, subQueryScore, valSrcScore); 22 //修改评分标准 23 return subQueryScore + (float)Math.random(); 24 } 25 } 26 /** 27 * 按照指定的排序方式进行排序 28 * @param key 29 * @param sort 30 */ 31 public void search(String key){ 32 IndexReader reader =null; 33 IndexSearcher searcher = null; 34 35 try{ 36 //1、创建reader对象 37 reader = util.getReader(FSDirectory.open(new File(path))); 38 39 //2、创建Searcher对象 40 searcher = util.getSeacher(reader); 41 42 //3、创建Query 43 Query query = new TermQuery(new Term("content",key)); 44 45 //创建valSrcQuery对象 46 47 //应用自定义ScoreQuery 48 BookScoreQuery scoreQuery = new BookScoreQuery(query); 49 50 //4、获取TopDocs 51 TopDocs tds =searcher.search(scoreQuery, 100); 52 53 54 //5、获取ScoreDoc 55 ScoreDoc[] sds = tds.scoreDocs; 56 57 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 58 //6、处理数据 59 for(ScoreDoc sd : sds){ 60 Document doc =searcher.doc(sd.doc); 61 62 System.out.println(sd.doc + "、(" + sd.score + " | "+doc.get("score2")+")" + 63 " **【" +doc.get("filename") + " ** " + doc.get("size")+ " ** " + 64 sdf.format(new Date(Long.parseLong(doc.get("modifydate"))))+ " ** " + doc.get("path")+"】"); 65 } 66 } 67 catch(Exception e){ 68 e.printStackTrace(); 69 } 70 finally{ 71 try { 72 searcher.close(); 73 } catch (IOException e) { 74 // TODO Auto-generated catch block 75 e.printStackTrace(); 76 } 77 } 78 }
【自定义评分】
1 /** 2 * 扩展名查询器 3 * @author Terry 4 * 5 */ 6 public class ExtScoreQuery extends CustomScoreQuery{ 7 8 public ExtScoreQuery(Query subQuery) { 9 super(subQuery); 10 } 11 12 @Override 13 protected CustomScoreProvider getCustomScoreProvider(IndexReader reader) 14 throws IOException { 15 //return super.getCustomScoreProvider(reader); 16 return new ExtScoreProvider(reader); 17 } 18 }
1 /** 2 * 实现自定义评分类 3 * @author Terry 4 * 5 */ 6 class ExtScoreProvider extends CustomScoreProvider{ 7 private String names[] = null; 8 9 public ExtScoreProvider(IndexReader reader) { 10 super(reader); 11 12 try { 13 //获取文件名列表 14 names = FieldCache.DEFAULT.getStrings(reader, "filename"); 15 } catch (IOException e) { 16 // TODO Auto-generated catch block 17 e.printStackTrace(); 18 } 19 } 20 21 /** 22 * ini、dat后缀名的文件评分+10 23 * 其他后缀名的文件评分呢-.5 24 */ 25 @Override 26 public float customScore(int doc, float subQueryScore, float valSrcScore) 27 throws IOException { 28 29 if(names != null && names.length>0){ 30 //获取当前文件名 31 String name = names[doc]; 32 33 //判断文件的后缀名是否为.ini或.dat 34 if(name.endsWith(".ini") || name.endsWith(".dat")) 35 return subQueryScore +10; 36 } 37 38 return subQueryScore -.5f; 39 //return super.customScore(doc, subQueryScore, valSrcScore); 40 } 41 42 }
1 /** 2 * 按照指定的排序方式进行排序 3 * @param key 4 * @param sort 5 */ 6 public void search(String key){ 7 IndexReader reader =null; 8 IndexSearcher searcher = null; 9 10 try{ 11 //1、创建reader对象 12 reader = util.getReader(FSDirectory.open(new File(path))); 13 14 //2、创建Searcher对象 15 searcher = util.getSeacher(reader); 16 17 //3、创建Query 18 Query query = new TermQuery(new Term("content",key)); 19 20 //创建valSrcQuery对象 21 22 //应用自定义ScoreQuery 23 //BookScoreQuery scoreQuery = new BookScoreQuery(query); 24 ExtScoreQuery scoreQuery = new ExtScoreQuery(query); 25 26 //4、获取TopDocs 27 TopDocs tds =searcher.search(scoreQuery, 100); 28 29 30 //5、获取ScoreDoc 31 ScoreDoc[] sds = tds.scoreDocs; 32 33 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 34 //6、处理数据 35 for(ScoreDoc sd : sds){ 36 Document doc =searcher.doc(sd.doc); 37 38 System.out.println(sd.doc + "、(" + sd.score + " | "+doc.get("score2")+")" + 39 " **【" +doc.get("filename") + " ** " + doc.get("size")+ " ** " + 40 sdf.format(new Date(Long.parseLong(doc.get("modifydate"))))+ " ** " + doc.get("path")+"】"); 41 } 42 } 43 catch(Exception e){ 44 e.printStackTrace(); 45 } 46 finally{ 47 try { 48 searcher.close(); 49 } catch (IOException e) { 50 // TODO Auto-generated catch block 51 e.printStackTrace(); 52 } 53 } 54 }
【自定义parser】
默认情况下Lucene支持WildCarQuery、FuzzyQuery等多种不同的搜索方式。但是其中部分搜索方式的搜索效率较低,实际使用时可能会被禁止使用。
【示例】
1 /** 2 * 创建自定义Parser 3 * @author Terry 4 * 5 */ 6 public class MyParser extends QueryParser{ 7 8 //实现Parser的构造函数 9 public MyParser(Version matchVersion, String f, Analyzer a) { 10 super(matchVersion, f, a); 11 12 System.out.println("MyParser被实例化了......"); 13 } 14 15 /** 16 * 重写getWildcardQuery()方法 17 */ 18 @Override 19 protected org.apache.lucene.search.Query getWildcardQuery(String field, 20 String termStr) throws ParseException { 21 //System.out.println("getWildcardQuery()方法被调用了......"); 22 //return super.getWildcardQuery(field, termStr); 23 24 throw new ParseException("系统目前不支持通配符查询,请使用精确搜索"); 25 } 26 27 /** 28 * 重写getFuzzyQuery() 29 */ 30 @Override 31 protected org.apache.lucene.search.Query getFuzzyQuery(String field, 32 String termStr, float minSimilarity) throws ParseException { 33 // TODO Auto-generated method stub 34 //return super.getFuzzyQuery(field, termStr, minSimilarity); 35 throw new ParserException("目前不支持模糊查询,请使用精准搜索"); 36 } 37 38 @Override 39 public String toString() { 40 return "MyParser [toString()=" + super.toString() + "]"; 41 } 42 43 }
1 /** 2 * 按照指定的排序方式进行排序 3 * @param key 4 * @param sort 5 */ 6 public void search(String key){ 7 IndexReader reader =null; 8 IndexSearcher searcher = null; 9 10 try{ 11 //1、创建reader对象 12 reader = util.getReader(FSDirectory.open(new File(path))); 13 14 //2、创建Searcher对象 15 searcher = util.getSeacher(reader); 16 17 //3、创建Query 18 //QueryParser parser = new QueryParser(util.VERSION,"content",new StandardAnalyzer(util.VERSION)); 19 QueryParser parser = new MyParser(util.VERSION,"content",new StandardAnalyzer(util.VERSION)); 20 Query query = parser.parse(key); 21 22 System.out.println(parser.toString()); 23 24 //4、获取TopDocs 25 TopDocs tds =searcher.search(query, 100); 26 27 28 //5、获取ScoreDoc 29 ScoreDoc[] sds = tds.scoreDocs; 30 31 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 32 //6、处理数据 33 for(ScoreDoc sd : sds){ 34 Document doc =searcher.doc(sd.doc); 35 36 System.out.println(sd.doc + "、(" + sd.score + " | "+doc.get("score2")+")" + 37 " **【" +doc.get("filename") + " ** " + doc.get("size")+ " ** " + 38 sdf.format(new Date(Long.parseLong(doc.get("modifydate"))))+ " ** " + doc.get("path")+"】"); 39 } 40 } 41 catch(Exception e){ 42 System.out.println(e.getMessage()); 43 } 44 finally{ 45 try { 46 searcher.close(); 47 } catch (IOException e) { 48 // TODO Auto-generated catch block 49 e.printStackTrace(); 50 } 51 } 52 }
1 @Test 2 public void test01(){ 3 ParserUtil util = new ParserUtil(); 4 //通配符查询。 5 //util.search("content:about????"); 6 //不支持,需要修改属性 7 //util.search("*about"); 8 //util.search("abount"); 9 //模糊查询 10 util.search("about~"); 11 }