lucene当中的各种query(三)

MultiTermQuery包含以下query:

FuzzyQuery, NumericRangeQuery, PrefixQuery, TermRangeQuery, WildcardQuery

FuzzyQuery是一种模糊查询,它可以简单地识别两个相近的词语。 即相似度匹配

NumericRangeQuery数字形式的范围查询

PrefixQuery前缀搜索A Query that matches documents containing terms with a specified prefix. A PrefixQuery is built by QueryParser for input like app*.

TermRangeQuery:主要用于文本范围查找;

使用通配符查询,*代表0个或多个字母,?代表0个或1个字母。

Query query=new WildcardQuery(new Term("contents","?ild*"));

Hits hits=searcher.search(query);

使用QueryParser和wildcardQuery使用的是相同的语法。但使用QueryParser时,首个字母不能是通配符

 


SpanQuery按照词在文章中的距离或者查询几个相邻词的查询

SpanQuery包括以下几种:

SpanTermQuery:词距查询的基础,结果和TermQuery相似,只不过是增加了查询结果中单词的距离信息。

SpanFirstQuery:在指定距离可以找到第一个单词的查询。

SpanNearQuery:查询的几个语句之间保持者一定的距离。

SpanOrQuery:同时查询几个词句查询。

SpanNotQuery:从一个词距查询结果中,去除一个词距查询。

 

 

ConstantScoreQuery

A query that wraps a filter and simply returns a constant score equal to the query boost for every document in the filter

看了一下这个类的构造函数ConstantScoreQuery(Filter filter) ,我的理解就是通过构造filter来完成文档的过滤,并且返回一个复合当前过滤条件的文档的常量分数,这个分数等于为查询条件设置的boost

 

 

 

2、自定义评分一、根据文件大小来评分,文件越大,权重越低

 

[java]  view plain copy
 
  1. package util;  
  2.   
  3. import java.io.IOException;  
  4. import org.apache.lucene.index.IndexReader;  
  5. import org.apache.lucene.index.Term;  
  6. import org.apache.lucene.search.IndexSearcher;  
  7. import org.apache.lucene.search.Query;  
  8. import org.apache.lucene.search.TermQuery;  
  9. import org.apache.lucene.search.TopDocs;  
  10. import org.apache.lucene.search.function.CustomScoreProvider;  
  11. import org.apache.lucene.search.function.CustomScoreQuery;  
  12. import org.apache.lucene.search.function.FieldScoreQuery;  
  13. import org.apache.lucene.search.function.ValueSourceQuery;  
  14. import org.apache.lucene.search.function.FieldScoreQuery.Type;  
  15.   
  16. public class MyScoreQuery1{  
  17.       
  18.     public void searchByScoreQuery() throws Exception{  
  19.         IndexSearcher searcher = DocUtil.getSearcher();  
  20.         Query query = new TermQuery(new Term("content","java"));  
  21.           
  22.         //1、创建评分域,如果Type是String类型,那么是Type.BYTE  
  23.         //该域必须是数值型的,并且不能使用norms索引,以及每个文档中该域只能由一个语汇  
  24.         //单元,通常可用Field.Index.not_analyzer_no_norms来进行创建索引  
  25.         FieldScoreQuery fieldScoreQuery = new FieldScoreQuery("size",Type.INT);  
  26.         //2、根据评分域和原有的Query创建自定义的Query对象  
  27.         //query是原有的query,fieldScoreQuery是专门做评分的query  
  28.         MyCustomScoreQuery customQuery = new MyCustomScoreQuery(query, fieldScoreQuery);  
  29.           
  30.         TopDocs topdoc = searcher.search(customQuery, 100);  
  31.         DocUtil.printDocument(topdoc, searcher);  
  32.         searcher.close();  
  33.           
  34.     }  
  35.       
  36.     @SuppressWarnings("serial")  
  37.     private class MyCustomScoreQuery extends CustomScoreQuery{  
  38.   
  39.         public MyCustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) {  
  40.             super(subQuery, valSrcQuery);  
  41.         }  
  42.           
  43.         /** 
  44.          * 这里的reader是针对段的,意思是如果索引包含的段不止一个,那么搜索期间会多次调用 
  45.          * 这个方法,强调这点是重要的,因为它使你的评分逻辑能够有效使用段reader来对域缓存 
  46.          * 中的值进行检索 
  47.          */  
  48.         @Override  
  49.         protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)  
  50.                 throws IOException {  
  51.             //默认情况实现的评分是通过原有的评分*传入进来的评分域所获取的评分来确定最终打分的  
  52.             //为了根据不同的需求进行评分,需要自己进行评分的设定  
  53.             /** 
  54.              * 自定评分的步骤 
  55.              * 创建一个类继承于CustomScoreProvider 
  56.              * 覆盖customScore方法 
  57.              */  
  58. //          return super.getCustomScoreProvider(reader);  
  59.             return new MyCustomScoreProvider(reader);  
  60.         }  
  61.           
  62.           
  63.     }  
  64.       
  65.     private class MyCustomScoreProvider extends CustomScoreProvider{  
  66.   
  67.         public MyCustomScoreProvider(IndexReader reader) {  
  68.             super(reader);  
  69.         }  
  70.           
  71.         /** 
  72.          * subQueryScore表示默认文档的打分 
  73.          * valSrcScore表示的评分域的打分 
  74.          * 默认是subQueryScore*valSrcScore返回的 
  75.          */  
  76.         @Override  
  77.         public float customScore(int doc, float subQueryScore, float valSrcScore)throws IOException {  
  78.             System.out.println("Doc:"+doc);  
  79.             System.out.println("subQueryScore:"+subQueryScore);  
  80.             System.out.println("valSrcScore:"+valSrcScore);  
  81. //          return super.customScore(doc, subQueryScore, valSrcScore);  
  82.             return subQueryScore / valSrcScore;  
  83.         }  
  84.           
  85.     }  
  86. }  


3、根据特定的几个文件名来评分,选中的文件名权重变大

 

 

[java]  view plain copy
 
  1. package util;  
  2.   
  3. import java.io.IOException;  
  4. import org.apache.lucene.index.IndexReader;  
  5. import org.apache.lucene.index.Term;  
  6. import org.apache.lucene.search.FieldCache;  
  7. import org.apache.lucene.search.IndexSearcher;  
  8. import org.apache.lucene.search.Query;  
  9. import org.apache.lucene.search.TermQuery;  
  10. import org.apache.lucene.search.TopDocs;  
  11. import org.apache.lucene.search.function.CustomScoreProvider;  
  12. import org.apache.lucene.search.function.CustomScoreQuery;  
  13. /** 
  14.  * 此类的功能是给特定的文件名加权,也就是加评分 
  15.  * 也可以实现搜索书籍的时候把近一两年的出版的图书给增加权重 
  16.  * @author user 
  17.  */  
  18. public class MyScoreQuery2 {  
  19.     public void searchByFileScoreQuery() throws Exception{  
  20.         IndexSearcher searcher = DocUtil.getSearcher();  
  21.         Query query = new TermQuery(new Term("content","java"));  
  22.           
  23.         FilenameScoreQuery fieldScoreQuery = new FilenameScoreQuery(query);  
  24.           
  25.         TopDocs topdoc = searcher.search(fieldScoreQuery, 100);  
  26.         DocUtil.printDocument(topdoc, searcher);  
  27.         searcher.close();  
  28.           
  29.     }  
  30.       
  31.     @SuppressWarnings("serial")  
  32.     private class FilenameScoreQuery extends CustomScoreQuery{  
  33.   
  34.         public FilenameScoreQuery(Query subQuery) {  
  35.             super(subQuery);  
  36.         }  
  37.   
  38.         @Override  
  39.         protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)  
  40.                 throws IOException {  
  41. //          return super.getCustomScoreProvider(reader);  
  42.             return new FilenameScoreProvider(reader);  
  43.         }  
  44.     }  
  45.       
  46.     private class FilenameScoreProvider extends CustomScoreProvider{  
  47.         String[] filenames = null;  
  48.         public FilenameScoreProvider(IndexReader reader) {  
  49.             super(reader);  
  50.             try {  
  51.                 filenames = FieldCache.DEFAULT.getStrings(reader, "filename");  
  52.             } catch (IOException e) {e.printStackTrace();}  
  53.         }  
  54.   
  55.         //如何根据doc获取相应的field的值  
  56.         /* 
  57.          * 在reader没有关闭之前,所有的数据会存储要一个域缓存中,可以通过域缓存获取很多有用 
  58.          * 的信息filenames = FieldCache.DEFAULT.getStrings(reader, "filename");可以获取 
  59.          * 所有的filename域的信息 
  60.          */  
  61.         @Override  
  62.         public float customScore(int doc, float subQueryScore, float valSrcScore)  
  63.                 throws IOException {  
  64.             String fileName = filenames[doc];  
  65.             System.out.println(doc+":"+fileName);  
  66. //          return super.customScore(doc, subQueryScore, valSrcScore);  
  67.             if("9.txt".equals(fileName) || "4.txt".equals(fileName)) {  
  68.                 return subQueryScore*1.5f;  
  69.             }  
  70.             return subQueryScore/1.5f;  
  71.         }  
  72.           
  73.     }  
  74. }  


4、测试junit

 

 

[java]  view plain copy
 
  1. package test;  
  2. import org.junit.Test;  
  3. import util.MyScoreQuery1;  
  4. import util.MyScoreQuery2;  
  5.   
  6. public class TestCustomScore {  
  7.   
  8.     @Test  
  9.     public void test01() throws Exception {  
  10.         MyScoreQuery1 msq = new MyScoreQuery1();  
  11.         msq.searchByScoreQuery();  
  12.     }  
  13.       
  14.     @Test  
  15.     public void test02() throws Exception {  
  16.         MyScoreQuery2 msq = new MyScoreQuery2();  
  17.         msq.searchByFileScoreQuery();  
  18.     }  
  19. }  


5、文档操作的工具类

 

 

[java]  view plain copy
 
  1. package util;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.text.SimpleDateFormat;  
  6. import java.util.Date;  
  7. import org.apache.lucene.document.Document;  
  8. import org.apache.lucene.index.CorruptIndexException;  
  9. import org.apache.lucene.index.IndexReader;  
  10. import org.apache.lucene.search.IndexSearcher;  
  11. import org.apache.lucene.search.ScoreDoc;  
  12. import org.apache.lucene.search.TopDocs;  
  13. import org.apache.lucene.store.Directory;  
  14. import org.apache.lucene.store.FSDirectory;  
  15.   
  16. public class DocUtil {  
  17.     private static IndexReader reader;  
  18.     //得到indexSearch对象  
  19.     public static IndexSearcher getSearcher(){  
  20.         try {  
  21.             Directory directory = FSDirectory.open(new File("D:\\Workspaces\\customscore\\index"));  
  22.             reader = IndexReader.open(directory);  
  23.         } catch (CorruptIndexException e) {  
  24.             e.printStackTrace();  
  25.         } catch (IOException e) {  
  26.             e.printStackTrace();  
  27.         }  
  28.         IndexSearcher searcher = new IndexSearcher(reader);  
  29.         return searcher;  
  30.     }  
  31.       
  32.     /** 
  33.      * 打印文档信息 
  34.      * @param topdoc 
  35.      */  
  36.     public static void printDocument(TopDocs topdoc,IndexSearcher searcher){  
  37.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");  
  38.         for(ScoreDoc scoredoc : topdoc.scoreDocs){  
  39.             try {  
  40.                 Document doc = searcher.doc(scoredoc.doc);  
  41.                 System.out.println(scoredoc.doc+":("+scoredoc.score+")" +  
  42.                         "["+doc.get("filename")+"【"+doc.get("path")+"】--->"+  
  43.                         doc.get("size")+"-----"+sdf.format(new Date(Long.valueOf(doc.get("date"))))+"]");  
  44.             } catch (CorruptIndexException e) {  
  45.                 e.printStackTrace();  
  46.             } catch (IOException e) {  
  47.                 e.printStackTrace();  
  48.             }  
  49.         }  
  50.     }  
  51. }  


6、创建索引

 

 

[java]  view plain copy
 
  1. package index;  
  2. import java.io.File;  
  3. import java.io.IOException;  
  4. import org.apache.commons.io.FileUtils;  
  5. import org.apache.lucene.analysis.Analyzer;  
  6. import org.apache.lucene.document.Document;  
  7. import org.apache.lucene.document.Field;  
  8. import org.apache.lucene.document.NumericField;  
  9. import org.apache.lucene.index.CorruptIndexException;  
  10. import org.apache.lucene.index.IndexWriter;  
  11. import org.apache.lucene.index.IndexWriterConfig;  
  12. import org.apache.lucene.store.Directory;  
  13. import org.apache.lucene.store.FSDirectory;  
  14. import org.apache.lucene.store.LockObtainFailedException;  
  15. import org.apache.lucene.util.Version;  
  16. import org.wltea.analyzer.lucene.IKAnalyzer;  
  17.   
  18. public class FileIndexUtils {  
  19.     private static Directory directory = null;  
  20.     private static Analyzer analyzer = new IKAnalyzer();  
  21.     public static void main(String[] args) {  
  22.         index(true);  
  23.     }  
  24.     static{  
  25.         try {  
  26.             directory = FSDirectory.open(new File("D:\\Workspaces\\customscore\\index"));  
  27.         } catch (IOException e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.     }  
  31.       
  32.     public static Directory getDirectory() {  
  33.         return directory;  
  34.     }  
  35.       
  36.     public static void index(boolean hasNew) {  
  37.         IndexWriter writer = null;  
  38.         try {  
  39.             writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_35, analyzer));  
  40.             if(hasNew) {  
  41.                 writer.deleteAll();  
  42.             }  
  43.             File file = new File("D:\\Workspaces\\customscore\\resource");  
  44.             Document doc = null;  
  45.             for(File f:file.listFiles()) {  
  46.                 doc = new Document();  
  47.                 doc.add(new Field("content",FileUtils.readFileToString(f),Field.Store.YES,Field.Index.ANALYZED));  
  48.                 doc.add(new Field("filename",f.getName(),Field.Store.YES,Field.Index.ANALYZED));  
  49.                 doc.add(new Field("classid","5312",Field.Store.YES,Field.Index.ANALYZED));  
  50.                 doc.add(new Field("path",f.getAbsolutePath(),Field.Store.YES,Field.Index.ANALYZED));  
  51.                 doc.add(new NumericField("date",Field.Store.YES,true).setLongValue(f.lastModified()));  
  52.                 doc.add(new NumericField("size",Field.Store.YES,true).setIntValue((int)(f.length())));  
  53.                 writer.addDocument(doc);  
  54.             }  
  55.         } catch (CorruptIndexException e) {  
  56.             e.printStackTrace();  
  57.         } catch (LockObtainFailedException e) {  
  58.             e.printStackTrace();  
  59.         } catch (IOException e) {  
  60.             e.printStackTrace();  
  61.         } finally {  
  62.             try {  
  63.                 if(writer!=null) writer.close();  
  64.             } catch (CorruptIndexException e) {  
  65.                 e.printStackTrace();  
  66.             } catch (IOException e) {  
  67.                 e.printStackTrace();  
  68.             }  
  69.         }  
  70.     }  
  71. }  


工程下载路径:http://download.csdn.net/detail/wxwzy738/5320772

 

 

http://blog.csdn.net/wxwzy738/article/details/8873094

猜你喜欢

转载自m635674608.iteye.com/blog/2235008