Lucene 高级搜索

自定义评分

public class MyScoreQuery {

     public void searchByScoreQuery(){
         try {
            IndexSearcher searcher=new IndexSearcher(IndexReader.open(FileIndexUtils.getDirectory()));
             Query q=new TermQuery(new Term("content","java"));
             //创建一个评分
             FieldScoreQuery fd=new FieldScoreQuery("score",Type.INT);
             //2 根据评分域和原有的Query创建自定义的Query对象
             MyCustomScoreQuery query=new MyCustomScoreQuery(q,fd);
             TopDocs tds=null;
             tds=searcher.search(query, 100);
             SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:ss");
             for(ScoreDoc sd:tds.scoreDocs){
                Document d=searcher.doc(sd.doc);
                System.out.println(sd.doc+"("+sd.score+")"+
                "["+d.get("filename")+"【"+d.get("path")+"】--->"+d.get("score")+"--->"+
                 d.get("size")+" "+sdf.format(new Date(Long.valueOf(d.get("date"))))+"]");
            }
             searcher.close();
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
     }
     

     public void searchByFileScoreQuery(){
         try {
            IndexSearcher searcher=new IndexSearcher(IndexReader.open(FileIndexUtils.getDirectory()));
             Query q=new TermQuery(new Term("content","java"));
            
             FilenameScoreQuery query=new FilenameScoreQuery(q);
             TopDocs tds=null;
             tds=searcher.search(query, 100);
             SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:ss");
             for(ScoreDoc sd:tds.scoreDocs){
                Document d=searcher.doc(sd.doc);
                System.out.println(sd.doc+"("+sd.score+")"+
                "["+d.get("filename")+"【"+d.get("path")+"】--->"+d.get("score")+"--->"+
                 d.get("size")+" "+sdf.format(new Date(Long.valueOf(d.get("date"))))+"]");
            }
             searcher.close();
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
     }
     
     
     
         private class DateScoreProvider extends CustomScoreProvider{
            long[] dates=null;
            public DateScoreProvider(IndexReader reader) {
                super(reader);
                //通过域缓存获取文件名
                try {
                    dates=FieldCache.DEFAULT.getLongs(reader, "date");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            
            @Override
            public float customScore(int doc, float subQueryScore, float valSrcScore) throws IOException {
                //如何个格局doc的名称获取相应的field的值
                /*
                 * 在reader在没有关闭之前,所有的数据会存储在一个域缓存中,可以通过域缓存获取很多有用的信息
                 */
                long date=dates[doc];
                long today=new Date().getTime();
                long year=1000*60*60*24*365;
                //表示的是这一年之内的
                if(today-date<=year){
                    //为其加分
                }
                
                
                return subQueryScore/1.5f;
            }
                
        }
         
     
     
     @SuppressWarnings("serial")
    private class FilenameScoreQuery extends CustomScoreQuery{

            public FilenameScoreQuery(Query subQuery) {
                super(subQuery);
                
            }

            @Override
            protected CustomScoreProvider getCustomScoreProvider(IndexReader reader) throws IOException {
                
                return  new FilenameScoreProvider(reader);
            }
            
     }
         
     private class FilenameScoreProvider extends CustomScoreProvider{
        String[] filenames=null;
        public FilenameScoreProvider(IndexReader reader) {
            super(reader);
            //通过域缓存获取文件名
            try {
                filenames=FieldCache.DEFAULT.getStrings(reader, "filename");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        @Override
        public float customScore(int doc, float subQueryScore, float valSrcScore) throws IOException {
            //如何个格局doc的名称获取相应的field的值
            /*
             * 在reader在没有关闭之前,所有的数据会存储在一个域缓存中,可以通过域缓存获取很多有用的信息
             */
            String filename=filenames[doc];
            System.out.println(filename);
            if(filename.endsWith("注解")|| filename .endsWith(".ini")){
                return subQueryScore*1.5f;
            }
            
            return subQueryScore/1.5f;
        }
            
    }
     
     private class MyCustomScoreQuery extends CustomScoreQuery{

        public MyCustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) {
            super(subQuery, valSrcQuery);
            
        }

        @Override
        protected CustomScoreProvider getCustomScoreProvider(IndexReader reader) throws IOException {
            //默认情况实现的评分是通过原有的评分 传入进来的评分域所获取的评分来确定最终打分
            //为了根据不同的需求进行评分,需要自己进行评分设定
            /**
             * 自定评分的步骤
             * 创建一个类继承于CustomScoreProvider
             * 覆盖customScore方法
             */
            return  new MyCustomScoreProvider(reader);
        }
        
     }
     
     private class MyCustomScoreProvider extends CustomScoreProvider{

        public MyCustomScoreProvider(IndexReader reader) {
            super(reader);
            // TODO Auto-generated constructor stub
        }
        
        /**
         * subQueryScore 表示默认文档的打分
         * valScrScore 表示的评分域的打分
         */

        @Override
        public float customScore(int doc, float subQueryScore, float valSrcScore) throws IOException {
            // TODO Auto-generated method stub
            return subQueryScore/valSrcScore;
        }
           
     }

}
View Code

 自定义Queryparser

public class CustomParser extends QueryParser {

    public CustomParser(Version matchVersion, String f, Analyzer a) {
        super(matchVersion, f, a);
    }

    @Override
    protected org.apache.lucene.search.Query getFuzzyQuery(String field, String termStr, float minSimilarity)
            throws ParseException {
        throw new ParseException("由于性能原因,已经禁用了模糊查询,请输入更精确的信息进行查询");
    }

    @Override
    protected org.apache.lucene.search.Query getWildcardQuery(String field, String termStr) throws ParseException {
        throw new ParseException("由于性能原因,已经禁用了通配符查询,请输入更精确的信息进行查询");

    }

    @Override
    protected org.apache.lucene.search.Query getRangeQuery(String field, String arg1, String arg2, boolean arg3)
            throws ParseException {
        //
        if(field.equals("size")){
            return NumericRangeQuery.newIntRange(field, Integer.parseInt(arg1), Integer.parseInt(arg2), arg3, arg3);
        }else if(field.equals("date")){
            //格式化日期
            String dateType="yyyy-MM-dd";
            Pattern pattern = Pattern.compile("\d{4}-\d{2}-\d{2}");
            if(pattern.matcher(arg1).matches() && pattern.matcher(arg2).matches()){
                SimpleDateFormat sdf=new SimpleDateFormat(dateType);
                try {
                    long start=sdf.parse(arg1).getTime();
                    long end=sdf.parse(arg2).getTime();
                    return NumericRangeQuery.newLongRange(field, start, end, arg3, arg3);
                } catch (java.text.ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        return new TermRangeQuery(field,arg1,arg2,arg3,arg3);
    }

}
View Code
原文地址:https://www.cnblogs.com/yaobolove/p/6688245.html