1.概述
Lucene是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。Lucene以其方便使用、快速实施以及灵活性受到广泛的关注。它可以方便地嵌入到各种应用中实现针对应用的全文索引、检索功能,本总结使用lucene--2.3.2。
2.lucene 的包结构
1、org.apache.lucene.analysis对需要建立索引的文本进行分词、过滤等操作, 语言分析器,主要用于的切词Analyzer是一个抽象类,管理对文本内容的切分词规则。
2、org.apache.lucene.analysis.standard是标准分析器
3、org.apache.lucene.document提供对Document和Field的各种操作的支持。索引存储时的文档结构管理,类似于关系型数据库的表结构。Document相对于关系型数据库的记录对象,Field主要负责字段的管理。
4、org.apache.lucene.index是最重要的包,用于向Lucene提供建立索引时各种操作的支持。索引管理,包括索引建立、删除等。索引包是整个系统核心,全文检索的根本就是为每个切出来的词建索引,查询时就只需要遍历索引,而不需要去正文中遍历,从而极大的提高检索效率。
5、org.apache.lucene.queryParser提供检索时的分析支持。查询分析器,实现查询关键词间的运算,如与、或、非等。
6、org.apache.lucene.search 负责检索。检索管理,根据查询条件,检索得到结果。
7、org.apache.lucene.store提供对索引存储的支持。数据存储管理,主要包括一些底层的I/0操作。
8、org.apache.lucene.util提供一些常用工具类和常量类的支持
3.索引文件格式
a).fnm格式包含了Document中所有field名称
b).fdt与.fdx格式.fdt文件用于存储具有Store.YES属性的Field的数据;.fdx是一个索
引,用于存储Document在.fdt中的位置。
c).tis 与.tii格式.tis文件用于存储分词后的词条(Term),而.tii就是它的索引文件,它
表明了每个.tis文件中的词条的位置。
d)deletable格式文档被删除后,会首先在deletable文件中留下一个记录,要真正删除时,
才将索引除去。
e)复合索引格式.cfs
使用IndexWriter的useCompoundFile() 默认为True
4.lucene中主要的类
4.1. Document文档类
4.1.1.常用方法
4.1.2.示例
Document doc1 = new Document();
doc1.add(new Field("name", "word1 word2 word3",
Field.Store.NO,Field.Index.TOKENIZED)); Document doc2 = new Document();
doc2.add(new Field("name", "word1 word2 word3",
Field.Store.NO,Field.Index.TOKENIZED));
4.2. Field字段类
4.2.1.构造方法
1)public Field(String name,String value,Store store,Index index);//直接的字符串方式
2)public Field(String name,String value,Store store,Index index,TermVector termVector);
3)public Field(String name,String value,Reader reader);//使用Reader从外部传入
4)public Field(String name,String value,Reader reader,TermVector termVector);
5)public Field(String name,byte[] value,Store store)//使用直接的二进制byte传入
当Field值为二进制时,可以使用Lucene的压缩功能将其值进行压缩。
4.2.2.Store类
4.2.3.Index类
4.2.4.示例
new Field("name", "word1 word2 word3",Field.Store.YES,Field.Index.TOKENIZED)
4.3. IndexWriter类
4.3.1.构造方法
1)public IndexWriter(String path,Analyzer a,Boolean create)
2)public IndexWriter(File path,Analyzer a,Boolean create)
3)public IndexWriter(Directory d,Analyzer a,Boolean create)
第一个参数:索引存放在什么地方
第二个参数:分析器,继承自org.apache.lucene.analysis.Analyzer类
第三个参数:为true时,IndexWriter不管目录内是否已经有索引了,一律清空,重新建立;当为false时,则IndexWriter会在原有基础上增量添加索引。所以在更新的过程中,需要设置该值为false。
4.3.2.添加文档
public void addDocument(Document doc)
public void addDocument(Document doc,Analyzer analyzer)//使用一个开发者自定义的,而非事先在构建IndexWriter时声明的Analyzer来进行分析
writer.addDocument(doc1);
4.3.3.性能参数
1)mergeFactor控制Lucene在把索引从内存写入磁盘上的文件系统时内存中最大的
Document数量,同时它还控制内存中最大的Segment数量。默认为10.
writer.setMergeFactor(10);
2)maxMergeDocs限制一个Segment中最大的文档数量。一个较大的maxMergeDocs适用
于对大批量的文档建立索引,增量式的索引则应使用较小的maxMergeDocs。
writer.setMaxMergeDocs(1000);
3)minMergeDocs用于控制内存中持有的文档数量的,它对磁盘上的Segment大小没有任
何影响。
4.3.4.限制Field的长度
maxFieldLength限制Field的长度,默认值为10000.最大值100000个。
public void setMaxFieldLength(int maxFieldLength)
writer.addDocument(doc1);
writer.setMaxFieldLength(100000);
writer.addDocument(doc2);
4.3.
5.复合索引格式
setUseCompoundFile(Boolean) 默认true
writer.setUseCompoundFile(true);//复合索引
writer.setUseCompoundFile(false);
4.3.6.优化索引
writer.optimize();
将磁盘上的多个segment进行合并,组成一个全新的segment。这种方法并不会增加建索时的速度,反而会降低建索的速度。所以应该在建完索引后在调用这个函数
4.3.7.示例
IndexWriter writer = new IndexWriter(path, new StandardAnalyzer(), true);
writer.addDocument(doc1);
writer.addDocument(doc2);
Sytem.out.println(writer.docCount());
writer.close();
IndexSearcher searcher = new IndexSearcher(path);
Hits hits = null;
Query query = null;
QueryParser parser =new QueryParser("name", new StandardAnalyzer());
query =parser.parse("word1");
hits = searcher.search(query);
System.out.println("查找word1 共" + hits.length() + "个结果");
4.4. Directory类
Directory:用于索引的存放位置
a)FSDirectory.getDirectory(path, true)第二个参数表示删除掉目录内原有内容IndexWriter writer = new IndexWriter(FSDirectory.getDirectory(path, true), new StandardAnalyzer(), true);//删除原有索引
或
FSDirectory fsDir=FSDirectory.getDirectory(path,true);
IndexWriter writer = new IndexWriter(fsDir, new StandardAnalyzer(), true);
b)RAMDirectory在内存中存放,读取速度快,但程序一运行结束,它的内容就不存在了RAMDirectory ramDir=new RAMDirectory();
IndexWriter writer = new IndexWriter(ramDir, new StandardAnalyzer(), true);
或
IndexWriter writer = new IndexWriter(new RAMDirectory(), new StandardAnalyzer(), true); 4.5. IndexReader类
IndexReader类――索引的读取工具
4.5.1.删除文档
IndexReader reader=IndexReader.open(path);
reader.deleteDocument(0);//删除第一个
reader.close();
4.5.2.反删除
reader.undeleteAll();
4.5.3.按字段删除
reader.deleteDocuments(new Term("name","word1"));
若要真正物理删除,则只需使用IndexWriter对索引optimize一次即可!
4.5.4.示例
IndexReader reader=IndexReader.open(path);
for(int i=0;i System.out.println(reader.document(i)); } System.out.println("版本:"+reader.getVersion()); System.out.println("索引内的文档数量:"+reader.numDocs()); //reader.deleteDocuments(new Term("name","word1")); Term term1=new Term("name","word1"); TermDocs docs=reader.termDocs(term1); while(docs.next()) { System.out.println("含有所查找的"+term1+"的Document的编号为"+docs.doc()); System.out.println("Term在文档中的出现次数"+docs.freq()); } reader.close(); 4.6. IndexModifier类 集成了IndexWriter的大部分功能和IndexReader中对索引删除的功能------ Lucene2.0的新类 4.6.1.示例 public static void main(String[] args) throws Exception { IndexModifier modifier=new IndexModifier("C:\\Q1",new StandardAnalyzer(),true); Document doc1=new Document(); doc1.add(new Field("bookname","钢铁是怎样炼成的 ",Field.Store.YES,Field.Index.TOKENIZED)); Document doc2=new Document(); doc2.add(new Field("bookname","山山水水 ",Field.Store.YES,Field.Index.TOKENIZED)); modifier.addDocument(doc1); modifier.addDocument(doc2); System.out.println(modifier.docCount()); modifier.setUseCompoundFile(false); modifier.close(); IndexModifier mo=new IndexModifier("C:\\Q1",new StandardAnalyzer(),false); mo.deleteDocument(0); System.out.println(mo.docCount()); mo.close(); } 4.7. IndexSearcher类 4.7.1.构造方法 IndexSearcher searcher = new IndexSearcher(String path); IndexSearcher searcher = new IndexSearcher(Directory directory); IndexSearcher searcher = new IndexSearcher(IndexReader r); IndexSearcher searcher = new IndexSearcher(IndexReader r,Boolean closeReader); IndexSearcher searcher = new IndexSearcher(path); IndexSearcher searcher = new IndexSearcher(FSDirectory.getDirectory(path,false) ); 4.7.2.search方法 //返回Hits对象 public Hits search(Query query) public Hits search(Query query,Filter filter) public Hits search(Query query,Sort sort) public Hits search(Query query,Filter filter,Sort sort) //检索只返回得分最高的Document public TopDocs search(Query query,Filter filter,int n) public TopDocs search(Weight weight,Filter filter,int n) public TopFieldDocs search(Weight weight,Filter filter,int n,Sort sort) public TopFieldDocs search(Query query,Filter filter,int n,Sort sort) //传入HitCollector,将结果保存在HitCollector中 public void search(Query query,HitCollector results) public void search(Query query,Filter filter,HitCollector results) public void search(Weight weight,Filter filter,HitCollector results) 4.7.3.Searcher的explain方法 public Explaination explain(Query query,int doc)throws IOException for(int i=0;i { Document d=hits.doc(i); System.out.println(i+" "+hits.score(i)+" "+d.get("contents")); System.out.println(searcher.explain(query,hits.id(i)).toString()) ; } 4.7.4.示例 IndexSearcher searcher = new IndexSearcher(path); Hits hits = null; Query query = null; QueryParser parser =new QueryParser("contents", new StandardAnalyzer()); query =parser.parse("11"); hits = searcher.search(query); System.out.println("查找 word1 共" + hits.length() + "个结果"); for(int i=0;i { Document d=hits.doc(i); System.out.println(d+" "+i+" "+hits.score(i)+" "+d.get("contents")); } searcher.close(); 4.8. Hits类 4.8.1.概述 Hits类――检索结果 4.8.2.常用方法 4.8.3.示例 for(int i=0;i { Document d=hits.doc(i); System.out.println(d+" "+" "+hits.score(i)+" "+d.get("contents")); System.out.println("文档的内部ID号:" + hits.id(i)); } 4.9. QueryParser类 4.9.1.改变默认的布尔逻辑 默认为“或”关系 Query query = null; QueryParser parser =new QueryParser("contents", new StandardAnalyzer()); query =parser.parse("hello world!"); System.out.println(query.toString()); 改变默认布尔逻辑 Query query = null; QueryParser parser =new QueryParser("contents", new StandardAnalyzer()); parser.setDefaultOperator(QueryParser.AND_OPERATOR); query =parser.parse("hello world");//若world后加!会出错 System.out.println(query.toString()); AND OR NOT –关键字 也可以不用改变默认布尔逻辑,而直接让用户在输入关键字时指定不同词条间的布尔联系。例如,用户输入hello AND world 必须为大写 逻辑与:AND (大写) 逻辑或:OR (大写) 逻辑非:- 例如:hello - world 也可以是NOT 例如:hello NOT world 4.9.2.不需要分词 不进行分词,将其完整的作为一个词条进行处理,则需要在词组的外面加上引号 String queryStr="\"God helps those who help themselves\""; QueryParser parser = new QueryParser("bookname",new StandardAnalyzer()); parser.setDefaultOperator(QueryParser.AND_OPERATOR); Query query=parser.parse(queryStr); System.out.println(query.toString()); 4.9.3.设置坡度值,支持FuzzyQuery String queryStr="\"God helps those who help themselves\"~1";//设置坡度为1 QueryParser parser = new QueryParser("bookname",new StandardAnalyzer()); Query query=parser.parse(queryStr); System.out.println(query.toString()); 4.9.4.设置通配符,支持WildcardQuery String queryStr="wor?" QueryParser parser = new QueryParser("bookname",new StandardAnalyzer()); parser.setDefaultOperator(QueryParser.AND_OPERATOR); Query query=parser.parse(queryStr); System.out.println(query.toString()); 4.9. 5.查找指定的Field String queryStr="linux publishdate:2006-09-01"; QueryParser parser = new QueryParser("bookname",new StandardAnalyzer()); parser.setDefaultOperator(QueryParser.AND_OPERATOR); Query query=parser.parse(queryStr); System.out.println(query.toString()); 例如:要求用户选择某一方面的 4.9.6.范围的查找,支持RangeQuery String queryStr="[1990-01-01 TO 1998-12-31]"; QueryParser parser=new QueryParser("publishdate", new StandardAnalyzer()); Query query=parser.parse(queryStr); System.out.println(query.toString()); 输出结果为publishdate:[081xmghs0 TO 0boeetj3z] 因为建立索引时,如果按照日期表示的字符串来进行索引,实际上比较的是字符串的字典顺序。而首先将日期转为以毫秒计算的时间后,则可以精确地比较两个日期的大小了。于是,lucene提供DateTools工具,用来完成其内部对时间的转化和处理,将毫秒级的时间转化为一个长字符串来进行表示,并进行索引。所以,遇到日期型数据时,最好用DateTools进行转换,再进行索引! 4.9.7.现在还不支持SpanQuery 4.10. MultiFieldQueryParser类--多域搜索 //在不同的Field上进行不同的查找 public static Query parse(String []queries,String[] fields,Analyzer analyzer)throws ParseException //在不同的Field上进行同一个查找,指定它们之间的布尔关系 public static Query parse(String query,String[] fields,BooleanClause.Occur[] flags,Analyzer analyzer) throws ParseException //在不同的Field上进行不同的查找,指定它们之间的布尔关系 public static Query parse(String []queries,String [] fields,BooleanClause.Occur[] flags,Analyzer analyzer)throws ParseException String [] queries={"钢", "[10 TO 20]"}; String[] fields={“bookname”,”price”}; BooleanClause.Occur[] clauses={BooleanClause.Occur.MUST,BooleanClause.Occur.MUST}; Query query=MultiFieldQueryParser.parse(queries,fields,clauses,new StandardAnalyzer()); System.out.println(query.toString()); 4.11. MultiSearcher类--多个索引搜索 IndexSearcher searcher1=new IndexSearcher(path1); IndexSearcher searcher2=new IndexSearcher(path2); IndexSeacher [] searchers={searcher1,seacher2}; MultiSearcher searcher=new MultiSearcher(searchers); Hits hits=searcher.search(query); for(int i=0;i System.out.println(hits.doc(i)); } 4.12. ParalellMultiSearcher类---多线程搜索 IndexSearcher searcher1=new IndexSearcher(path1); IndexSearcher searcher2=new IndexSearcher(path2); IndexSearcher [] searchers={searcher1,searcher2}; ParallelMultiSearcher searcher=new ParallelMultiSearcher(searchers); long start=System.currentTimeMillis(); Hits hits=searcher.search(query); long end=System.currentTimeMillis(); System.out.println((end-start)+"ms"); 5.排序 5.1. Sort类 public Sort() public Sort(String field) public Sort(String field,Boolean reverse) //默认为false,降序排序 public Sort(String[] fields) public Sort(SortField field) public Sort(SortField[] fields) Sort sort=new Sort(“bookname”);按照“bookname“这个Field值进行降序排序Sort sort=new Sort(“bookname”,true) //升序排序 Sort sort=new Sort(new String[]{“bookNumber”,”bookname”,”publishdate”});按照三个Field进行排序,但无法指定升序排序,所以用SortField 5.2. SortField类 public SortField(String field) public SortField(String field,Boolean reverse) public SortField(String field,int type) //type表示当前Field值的类型 public SortField(String field,int type,boolean reverse) //默认为false,升序 Field值的类型:SortField.STRING、SortField.INT、SortField.FLOAT SortField sf1=new SortField(“bookNumber”,SortField.INT,fals e); SortField sf2=new SortField(“bookname”,SortField.STRING,false); 5.3. 指定排序的法则 5.3.1.按照文档的得分降序排序 Hits hits=searcher.search(query,Sort.RELEVANCE); 5.3.2.按文档的内部ID升序排序 Hits hits=searcher.search(query, Sort.INDEXORDER); 5.3.3.按照一个Field来排序 Sort sort=new Sort(); SortField sf=new Sor tField(“bookNumber”,SortField.INT,false); sort.setSort(sf); Hits hits=searcher.search(query,sort); 5.3.4.按照多个Field来排序 Sort sort=new Sort(); SortField sf1=new SortField(“bookNumber”,SortField.INT,false);//升序SortField sf2=new SortField(“publishdate”,SortField.STRING,true);//降序 sort.setSort(new SortField[]{sf1,sf2}); Hits hits=searcher.search(query,sort); 5.3.5.改变SortField中的Locale信息 String str1=”我”; String str2=”你”; Collator co1=Collator.getInstance(Locale.CHINA); Collator co2=Collator.getInstance(Locale.JAPAN); System.out.println(Locale.CHINA+”:”+https://www.doczj.com/doc/966874521.html,pare(str1,str2)); System.out.println(Locale.JAPAN+”:”+https://www.doczj.com/doc/966874521.html,pare(str1,str2)); 输出结果为: zh_CN:1 ja_JP:-1 所以 public SortField(String field,Locale locale) public SortField(String field,Locale locale,boolean reverse) 6.过滤器 使用public Hits search(Query query,Filter filter) (1)简单过滤 Hits hits=searcher.search(query,new AdvancedSecurityFilter());//过滤掉securitylevel为0的结果 (2)范围过滤—RangeFilter 只显示中间的 RangeFilter filter=new RangeFilter(“publishdate”,”1970-01-01”,”1998-12-31”,true,true”); Hits hits=searcher.search(query,filter); 无上边界 public static RangeFilter More(String fieldname,String lowerTerm) 无下边界 public static RangeFilter Less(String fieldname,String upperTerm) (3)在结果中查询QueryFilter RangeQuery q=new RangeQuery(new Term(“publicshdate”,”1970-01-01”), new Term(“publishdate”,”1999-01-01”),true); QueryFilter filter=new QueryFilter(q); Hits hits=searcher.search(query,filter); 7.分析器Analysis 7.1. 自带分析器和过滤器 标准过滤器:StandardAnalyzer 大小写转换器:LowerCaseFilter 忽略词过滤器:StopFilter public StopFilter(TokenStream input,String [] stopWords) public StopFilter(TokenStream in,String [] stopWords,boolean ignoreCase) public StopFilter(TokenStream input,Set stopWords,boolean ignoreCase) public StopFilter(TokenStream in, Set stopWords) 其中,参数TokenStream代表当前正在进行处理的流;String类型的数组代表一个用数组表示的忽略词集合;Set类型的参数与String一样,是用来表示忽略词集合的;boolean表示当 与忽略词集合中的词进行匹配时,是否需要忽略大小写。 长度过滤器:LengthFilter PerFieldAnalyzerWrapper WhitespaceAnalyzer String str="str1 str2 str3"; StringReader reader=new StringReader(str); Analyzer anlyzer=new WhitespaceAnalyzer(); TokenStream ts=anlyzer.tokenStream("", reader); Token t=null; while( (t=ts.next())!=null ){ System.out.println(t.termText()); } 7.2. 第三方过分析器 单字分词 二分法:CJKAnalyzer、中科院ICTCLAS分词、JE分词 词典分词 7.2.1.JE分词用法 7.2.1.1. 示例 import jeasy.analysis.MMAnalyzer; IndexWriter writer = new IndexWriter(INDEX_STORE_PATH, new MMAnalyzer() , true); String str=" Lucene是一个全文检索引擎的架构,"+ "提供了完整的查询引擎和索引引擎。Lucene以其方便使用、快" + "速实施以及灵活性受到广泛的关注。它可以方便地嵌入到各种应用" + "中实现针对应用的全文索引、检索功能,本总结使用lucene--2.3.2。"; MMAnalyzer analyzer=new MMAnalyzer(); try{ System.out.println(analyzer.segment(str, "|")); } catch(Exception e) { e.printStackTrace(); } 输出结果:lucene|一个|全文|检索|引擎|架构|提供|完整|查询|。。。。 7.2.1.2. 设定正向最大匹配的字数 MMAnalyzer analyzer=new MMAnalyzer(4); 7.2.1.3. 添加新词 MMAnalyzer.addWord(String word); MMAnalyzer.addDictionary(Reader reader); MMAnalyzer analyzer=new MMAnalyzer(); MMAnalyzer.addWord("迈克尔雷第"); 8.索引的合并 RAMDirectory RAMDir=new RAMDirectory(); IndexWriter writer = new IndexWriter(RAMDir, new StandardAnalyzer(), true);//删除原有索引 IndexWriter writer2=new IndexWriter(FSDirectory.getDirectory(path,true), new StandardAnalyzer(), true); writer.addDocument(doc1); writer2.addDocument(doc2); writer.close(); writer2.addIndexes(new Directory[]{RAMDir}); writer2.close(); 注意:在合并前一定要先关闭要加的索引器。 9.各种Query 9.1. 概述 query.toString()查看原子查询 9.2. 使用特定的分析器搜索 IndexSearcher searcher = new IndexSearcher(path ); Hits hits = null; Query query = null; QueryParser parser =new QueryParser("contents", new StandardAnalyzer()); query =parser.parse("11 a and hello"); hits=searcher.search(query); //查找 name:11 name:hello 共1个结果 System.out.println("查找 "+query.toString()+" 共" + hits.length() + "个结果"); 9.3. 按词条搜索—TermQuery Query query = null; query=new TermQuery(new Term("name","word1 a and")); hits=searcher.search(query);// 查找 name:word1 a and 共0个结果 System.out.println("查找 "+query.toString()+" 共" + hits.length() + "个结果"); 9.4. 按“与或”搜索—BooleanQuery 1.和:MUST与MUST_NOT 2.或:SHOULD与SHOULD 3.A与B的并集-B MUST与MUST_NOT Query query1=null; Query query2=null; BooleanQuery query=null; query1=new TermQuery(new Term("name","word1")); query2=new TermQuery(new Term("name","word2")); query=new BooleanQuery(); query.add(query1,BooleanClause.Occur.MUST); query.add(query2,BooleanClause.Occur.MUST_NOT); 9.5. 在某一范围内搜索—RangeQuery Term beginTime=new Term("time","200001"); Term endTime=new Term("time","200005"); RangeQuery query=null; query=new RangeQuery(beginTime,endTime,false);//不包含边界值 9.6. 使用前缀搜索—PrefixQuery Term pre1=new Term("name","wor"); PrefixQuery query=null; query = new PrefixQuery(pre1); 9.7. 短语搜索—PhraseQuery a)默认坡度为0 PhraseQuery query = new PhraseQuery(); query.add(new Term(“bookname”,”钢”)); query.add(new Term(“bookname”,”铁”)); Hits hits=searcher.search(query); //搜索“钢铁”短语,而非“钢”和“铁” b)设置坡度,默认为0 PhraseQuery query = new PhraseQuery(); query.add(new Term(“bookname”,”钢”)); query.add(new Term(“bookname”,”铁”)); query.setSlop(1); Hits hits=searcher.search(query);//搜索“钢铁”或“钢*铁”中含一字 9.8. 多短语搜索—MultiPhraseQuery a) MultiPhraseQuery query=new MultiPhraseQuery(); //首先向其中加入要查找的短语的前缀 query.add(new Term(“bookname”,”钢”)); //构建3个Term,作为短语的后缀 Term t1=new Term(“bookname”,”铁”); Term t2=new Term(“bookname”,”和”); Term t3=new Term(“bookname”,”要”); //再向query中加入所有的后缀,与前缀一起,它们将组成3个短语 query.add(new Term[]{t1,t2,t3}); Hits hits=searcher.search(query); for(int i=0;i System.out.println(hits.doc(i)); b) MultiPhraseQuery query=new MultiPhraseQuery(); Term t1=new Term(“bookname”,”钢”); Term t2 = new Term(“bookname”,”和”); query.add(new Term[]{t1,t2}); query.add(new Term(“bookname”,”铁”)); c) MultiPhraseQuery query=new MultiPhraseQuery(); Term t1=new Term(“bookname”,”钢”); Term t2 = new Term(“bookname”,”和”); query.add(new Term[]{t1,t2}); query.add(new Term(“bookname”,”铁”)); Term t3=new Term(“bookname”,”是”); Term t4=new Term(“bookname”,”战”); query.add(new Term[]{t3,t4}); 9.9. 模糊搜索—FuzzyQuery 使用的算法为levenshtein算法,在比较两个字符串时,将动作分为3种: ●加一个字母 ●删一个字母 ●改变一个字母 FuzzyQuery query=new FuzzyQuery(new Term(“content”,”work”)); public FuzzyQuery(Term term) public FuzzyQuery(Term term,float minimumSimilarity)throws IllegalArgumentException public FuzzyQuery(Term term,float minimumSimilarity,int prefixLength)throws IllegalArgumentException 其中minimumSimilarity为最小相似度,越小则文档的数量越多。默认为0.5.其值必须<1.0 FuzzyQuery query=new FuzzyQuery(new Term(“content”,”work”),0.1f); 其中prefixLength表示要有多少个前缀字母必须完全匹配 FuzzyQuery query=new FuzzyQuery(new Term(“content”,”work”),0.1f,1); 9.10. 通配符搜索—WildcardQuery * 表示0到多个字符 ? 表示一个单一的字符 WildcardQuery query=new WildcardQuery(new Term(“content”,”?qq*”)); 9.11. 跨度搜索 9.11.1.SpanTermQuery 效果和TermQuery相同 SpanTermQuery query=new SpanTermQuery(new Term(“content”,”abc”)); 9.11.2.SpanFirstQuery 从Field内容的起始位置开始,在一个固定的宽度内查找所指定的词条 SpanFirstQuery query=new SpanFirstQuery(new Term(“content”,”abc”),3);//是第3个word,不是byte 9.11.3.SpanNearQuery SpanNearQuery相当与PhaseQuery SpanTermQuery people=new SpanTermQuery(new Term(“content”,”mary”)); SpanTermQuery how=new SpanTermQuery(new Term(“content”,”poor”)); SpanNearQuery query=new SpanNearQuery(new SpanQuery[]{people,how},3,false); 9.11.4.SpanOrQuery 把所有SpanQuery的结果合起来 SpanTermQuery s1=new SpanTermQuery(new Term(“content”,”aa”); SpanTermQuery s2=new SpanTermQuery(new Term(“content”,”cc”); SpanTermQuery s3=new SpanTermQuery(new Term(“content”,”gg”); SpanTermQuery s4=new SpanTermQuery(new Term(“content”,”kk”); SpanNearQuery query1=new SpanNearQuery(new SpanQuery[]{s1,s2},1,false); SpanNearQuery query2=new SpanNearQuery(new SpanQuery[]{s3,s4},3,false); SpanOrQuery query=new SpanOrQuery(new SpanQuery[]{query1,query2}); 9.11.5.SpanNotQuery 从第1个SpanQuery的查询结果中,去掉第2个SpanQuery的查询结果SpanTermQuery s1=new SpanTermQuery(new Term(“content”,”aa”); SpanFirstQuery query1=new SpanFirstQuery(s1,3); SpanTermQuery s3=new SpanTermQ uery(new Term(“content”,”gg”); SpanTermQuery s4=new SpanTermQuery(new Term(“content”,”kk”); SpanNearQuery query2=new SpanNearQuery(new SpanQuery[]{s3,s4},4,false); SpanNotQuery query=new SpanNotQuery(query1,query2); 9.12. RegexQuery—正则表达式的查询 String regex="http://[a-z]{1,3}\\.abc\\.com/.*"; RegexQuery query=new RegexQuery(new Term("url",regex));