zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    20201031
    20201028
    20201026
    20201027
    20201020
    ReentrantReadWriteLock原理分析
    java中Thread源码介绍
    CountDownLatch原理分析
    Semaphore原理分析
    AQS-共享模式分析
  • 原文地址:https://www.cnblogs.com/yaobolove/p/6688245.html
Copyright © 2011-2022 走看看