您的位置:首页 > 其它

【转载】lucene整理 -- 概念 搜索 排序

2013-03-04 15:54 309 查看
 
 
【摘录】
http://blog.csdn.net/xiaoping8411/article/details/5409940
 
lucene整理1 -- 概念
分类: lucene2010-03-23
22:34 52人阅读 评论(0) 收藏 举报
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
 
 


1.    lucene中主要的类


1.1. Document文档类


1.1.1.常用方法

方法
描述
void add(Field
field)
往Document对象中添加字段
void
removeField(String name)
删除字段。若多个字段以同一个字段名存在,则删除首先添加的字段;若不存在,则Document保持不变
void
removeFields(String name)
删除所有字段。若字段不存在,则Document保持不变
Field getField(String
name)
若多个字段以同一个字段名存在,则返回首先添加的字段;若字段不存在,则Document保持不变
Enumeration
fields()
返回Document对象的所有字段,以枚举类型返回
Field []
getFields(String name)
根据名称得到一个Field的数组
String []
getValues(String name)
根据名称得到一个Field的值的数组
 


1.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));


1.2. Field字段类


1.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的压缩功能将其值进行压缩。


1.2.2.Store类

静态属性
描述
Store.NO
表示该Field不需要存储
Store.YES
表示该Field需要存储
Store.COMPRESS
表示用压缩方式来保存这个Field的值


1.2.3.Index类

静态属性
描述
Index.NO
不需要索引
Index.TOKENIZED
先被分词再被索引
Index.UN_TOKENIZED
不对该Field进行分词,但会对它进行索引
Index.NO_NORMS
对该Field进行索引,但是不使用Analyzer,同时禁止它参加评分,主要是为了减少内存的消耗。
 


1.2.4.示例

new Field("name", "word1 word2
word3",Field.Store.YES,Field.Index.TOKENIZED)
 


1.3. IndexWriter类


1.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。


1.3.2.添加文档

public void addDocument(Document doc)
public void addDocument(Document doc,Analyzer analyzer)//使用一个开发者自定义的,而非事先在构建IndexWriter时声明的Analyzer来进行分析
writer.addDocument(doc1);


1.3.3.性能参数

1)        mergeFactor控制Lucene在把索引从内存写入磁盘上的文件系统时内存中最大的Document数量,同时它还控制内存中最大的Segment数量。默认为10.
writer.setMergeFactor(10);
2)        maxMergeDocs限制一个Segment中最大的文档数量。一个较大的maxMergeDocs适用于对大批量的文档建立索引,增量式的索引则应使用较小的maxMergeDocs。
writer.setMaxMergeDocs(1000);
3)        minMergeDocs用于控制内存中持有的文档数量的,它对磁盘上的Segment大小没有任何影响。


1.3.4.限制Field的长度

maxFieldLength限制Field的长度,默认值为10000.最大值100000个。
public void setMaxFieldLength(int maxFieldLength)
writer.addDocument(doc1);
writer.setMaxFieldLength(100000);
writer.addDocument(doc2);


1.3.5.复合索引格式

setUseCompoundFile(Boolean) 默认true
writer.setUseCompoundFile(true);//复合索引
writer.setUseCompoundFile(false);


1.3.6.优化索引

writer.optimize();
将磁盘上的多个segment进行合并,组成一个全新的segment。这种方法并不会增加建索时的速度,反而会降低建索的速度。所以应该在建完索引后在调用这个函数


1.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() + "个结果");
 


1.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);


1.5. IndexReader类

IndexReader类――索引的读取工具


1.5.1.删除文档

IndexReader reader=IndexReader.open(path);
reader.deleteDocument(0);//删除第一个
reader.close();


1.5.2.反删除

reader.undeleteAll();


1.5.3.按字段删除

reader.deleteDocuments(new
Term("name","word1"));
若要真正物理删除,则只需使用IndexWriter对索引optimize一次即可!


1.5.4.示例

IndexReader reader=IndexReader.open(path);
           for(int i=0;i<reader.numDocs();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();
 


1.6. IndexModifier类

集成了IndexWriter的大部分功能和IndexReader中对索引删除的功能 ------ Lucene2.0的新类
 


1.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();
    }
 


1.7. IndexSearcher类


1.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) );


1.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)


1.7.3.Searcher的explain方法

public Explaination explain(Query query,int doc)throws
IOException
for(int i=0;i<hits.length()&&i<10;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());
}


1.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<hits.length()&&i<10;i++)
{
    Document d=hits.doc(i);
    System.out.println(d+"
"+i+" "+hits.score(i)+"
"+d.get("contents"));
}
searcher.close();


1.8. Hits类


1.8.1.概述

Hits类――检索结果


1.8.2.常用方法

 
 
方法名
描述
int length()
返回搜索到结果的总数量
Document doc(int
i)
返回第i个文档
int id(int i)
返回第i个文档的内部ID号
float score(int
i)
返回第i个文档的得分
Iterator
iterator()
取得Hits集合的遍历对象


1.8.3.示例

for(int i=0;i<hits.length()&&i<10;i++)
{
    Document d=hits.doc(i);
    System.out.println(d+"
"+" "+hits.score(i)+" "+d.get("contents"));
System.out.println("文档的内部ID号:" +
hits.id(i));
}


1.9. QueryParser类


1.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


1.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());


1.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());


1.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());


1.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());
例如:要求用户选择某一方面的


1.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进行转换,再进行索引!


1.9.7.现在还不支持SpanQuery


1.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());
 


1.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<hits.length();i++){
    System.out.println(hits.doc(i));
}


1.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");
 


1.    排序


1.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


1.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,false);
SortField sf2=new
SortField(“bookname”,SortField.STRING,false);


1.3. 指定排序的法则


1.3.1.按照文档的得分降序排序

Hits
hits=searcher.search(query,Sort.RELEVANCE);


1.3.2.按文档的内部ID升序排序

Hits hits=searcher.search(query,
Sort.INDEXORDER);


1.3.3.按照一个Field来排序

Sort sort=new Sort();
SortField sf=new
SortField(“bookNumber”,SortField.INT,false);
sort.setSort(sf);
Hits hits=searcher.search(query,sort);


1.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);


1.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+”:”+co1.compare(str1,str2));
System.out.println(Locale.JAPAN+”:”+co2.compare(str1,str2));
输出结果为:
zh_CN:1
ja_JP:-1
所以
public SortField(String field,Locale
locale)
public SortField(String field,Locale
locale,boolean reverse)


2.    过滤器

使用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);


3.    分析器Analysis


3.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());
       }


3.2. 第三方过分析器

Ø         单字分词
Ø         二分法:CJKAnalyzer、中科院ICTCLAS分词、JE分词
Ø         词典分词


3.2.1.JE分词用法


3.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|一个|全文|检索|引擎|架构|提供|完整|查询|。。。。


3.2.1.2.    设定正向最大匹配的字数

MMAnalyzer analyzer=new MMAnalyzer(4);


3.2.1.3.    添加新词

MMAnalyzer.addWord(String word);
MMAnalyzer.addDictionary(Reader reader);
 
MMAnalyzer analyzer=new MMAnalyzer();
MMAnalyzer.addWord("迈克尔雷第");
 


4.    索引的合并

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();
注意:在合并前一定要先关闭要加的索引器。
 
 


1.    各种Query


1.1. 概述

query.toString()查看原子查询


1.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() + "个结果");


1.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() + "个结果");


1.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);


1.5. 在某一范围内搜索—RangeQuery

Term beginTime=new
Term("time","200001");
Term endTime=new
Term("time","200005");
RangeQuery query=null;
query=new
RangeQuery(beginTime,endTime,false);//不包含边界值


1.6. 使用前缀搜索—PrefixQuery

Term pre1=new
Term("name","wor");
PrefixQuery query=null;
query = new PrefixQuery(pre1);


1.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);//搜索“钢铁”或“钢*铁”中含一字


1.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<hits.length();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});


1.9. 模糊搜索—FuzzyQuery

使用的算法为levenshtein算法,在比较两个字符串时,将动作分为3种:
l         加一个字母
l         删一个字母
l         改变一个字母
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);


1.10.            通配符搜索—WildcardQuery

* 表示0到多个字符
? 表示一个单一的字符
WildcardQuery query=new
WildcardQuery(new Term(“content”,”?qq*”));


1.11.            跨度搜索


1.11.1.      SpanTermQuery

效果和TermQuery相同
SpanTermQuery query=new
SpanTermQuery(new Term(“content”,”abc”));


1.11.2.      SpanFirstQuery

从Field内容的起始位置开始,在一个固定的宽度内查找所指定的词条
SpanFirstQuery query=new
SpanFirstQuery(new Term(“content”,”abc”),3);//是第3个word,不是byte


1.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);


1.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});


1.11.5.      SpanNotQuery

从第1个SpanQuery的查询结果中,去掉第2个SpanQuery的查询结果
SpanTermQuery s1=new SpanTermQuery(new
Term(“content”,”aa”);
SpanFirstQuery query1=new
SpanFirstQuery(s1,3);
 
SpanTermQuery s3=new SpanTermQuery(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);


1.12.            RegexQuery—正则表达式的查询

String
regex="http://[a-z]{1,3}//.abc//.com/.*";
       RegexQuery query=new RegexQuery(new
Term("url",regex));
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: