例子:
IndexSearcher searcher = new IndexSearcher(“c://index”);
Query query = QueryParser.parse(“key1”,”name”,new StandardAnalyzer());
Hits hits = searcher.search(query);
If(hits.length()==0){
Out.println(“not found”);
}
else{
for(int i=0;i Document d = hits.doc(i);
Out.println(d.get(“title”));
}
}
文档搜索结果的主要排序依据是文档的分值。改变文档分值的方法是建立索引时,在初始化Document对象后,使用Document的setBoost方法来改变文档的boost因子(分值的倍数):
Document doc = new Document();
Doc.add(Field.Text(“contents”,”text1 text2”));
Doc.setBoost(1.5f); //改变因子,如0.3f,1.0f等
构建Query:
Query是search包中的一个抽象类,它有许多子类,代表不同类形的查询
关键字TermQuery
Term term = new Term(“contents”,”java”);//实质也是一个键/值对
//构造TermQuery
Query query = new TermQuery(term);
组合查询BooleanQuery
BooleanQuery是一个查询容器,提供专门的方法往其中加入查询,并标明条件的关系
IndexSearcher searcher = new IndexSearcher(“c://index”);
Query q1 = new TermQuery(new Term(“name”,”tim”));
Query q2 = new TermQuery(new Term(“name”,”fly”));
//构造容器
Query query = new BooleanQuery();
query.add(q1,true,false);
query..add(q2,true,false);
Hits hits = searcher.search(query);
BooleanQuery的add方法的第二,第三参数说明:第二参数表示是否必须满足,第三参数表示是否不需要满足,组合一起有以下三种情况:
True,false:当前查询条件是必须要满足的
False ,true:当前查询是不可以满足的
False,false:条件是可选的
True,true:这种情况是错误的
以上表明,上述例子的两个条件都是必须满足的,是“与(and)”的关系
如果查进行“或(or)”运算,相应地可改为:
query.add(q1,false,false);
query.add(q2,false,false)
范围搜索RangeQuery
RangeQuery query = new RangeQuery(begin,end,included);//最后参数为是否包含边界
例:
Term begin = new Term(“time”,”20050101”);
Term end = new Term(“time”,”20050202”);
RangeQuery query = new RangeQuery(begin,end,false);
前缀PrefixQuery
PrefixQuery query = new PrefixQuery(new Term(“name”,”ti”));//name字段中以ti开头
多关键字PhraseQuery
PhraseQuery query = new PhraseQuery();
Query.add(new Term(“content”,”hello”));
Query.add(new Term(“content”,”world”));
Query.setSlop(2);
//设置以上加上的两个关键字坡度,此值代表两个关键字之间无关词的个数.对于两个紧连的关键字,无论将坡度设为多少都能找到,如果两个词不紧连,且坡度值小于它们之间的无关词的数量,则无法找到
短词缀PhrasePrefixQuery
Term word1 = new Term(“content”,”david”);
Term word2 = new Term(“content”,”mary”);
Term word3 = new Term(“content”,”robert”);
PhrasePrefixQuery query = new PhrasePrefixQuery();
//加入不确定的词
Query.add(new Term[]{word1,word2});//不确定,第一个关键词在Term数组中产生
//加入确定的词
query.add(word3);
query.setSlop(2);//设置坡度
//以上查询中,david robert和mary robert都会出现在查询结果,同样地,mary and robert也会被击中
相近词FuzzyQuery
FuzzyQuery query = new FuzzyQuery(new Term(“content”,”david”));
通配符WildcardQuery
WildcardQuery query = new WildcardQuery(new Term(“content”,”*im”));
WildcardQuery query = new WildcardQuery(new Term(“content”,”t?m??”));
//*代表0个或多个字符,?一个字符
QueryParser类,把用户各种输入转为Query
Query query = QueryParser.parse(keywords,filedName,new StandardAnalyer());
关键字格式:
“tim” //在默认字段搜索tim
“name:tim”;//在name字段搜tim
“tim wong”或tim or wong;//在默认字段搜搜关键字tim 或wong
“+tim +wong”或”tim and wong” //搜索tim和 wong
”tim*”//在默认字段中搜前缀为tim的
“name:tim is a programer”;//在name字段中包含短语tim is a programer
“(tim or wong) and php” //在默认字段中搜含有tim 或wong的关键字,但一定要包含php
“name:tim –title:php” //name字段搜tim,并且title不含有php
另外,QueryParser构造时需要一个分析器,它应该与建立索引时的分析器一样
QueryParser的“与”和“或”
当输入两个关键字时,默认关系是或,要改变这种关系,方法是:
QueryParser parser = new QueryParser(keyword,fieldNmae,new StandardAnalyzer());
Parser.setOperator(QueryParser.DEFAULT_OPERATOR_AND);
排序及多字段查找
默认情况下,IndexSearcher类的search方法返回查询结果时,是按文档的分值排序的,可以使用重载的search方法对结果排序
IndexSearcher.search(Query,Sort);
new Sort() 和 Sort.RELEVANCE,以及null一样,采用默认排序,要定义排序字段,方法是将字段传入Sort对象
Sort sort = new Sort(String field);
也可以对多个字段排序Sort sort = new Sort(String[] fields);
例:
Sort sort = new Sort(new SortField[]{new SortField(“title”),new SortField(“name”)});
Hits hits=searcher.search(query,Sort);
多字段查找MultiFieldQueryParser
只在某些Term中查找,不关心在哪个字段
Query query = new MultiFieldQueryParser.parse(“word”,new String[]{“title”,”content”},analyzer); //在title和content中找word
多字段时默认是OR关系,要改变它,使用以下方法:
Query query = MultiFieldQueryParser.parse(“word”,new String[]{“title”,”content”},new int[]{MultiFieldQueryParser.REQUIRED_FIELD,MultiFieldQueryParser.PROHIBITED_FIELD},analyzer);
其中:
REQUIRED_FIELD 表示该条件必须有
PROHIBITED_FIELD 表示必须不含
搜索多个索引文件MultiSearcher
1) 建立多个索引:使用不同的索引目录,实例化不同的IndexWriter
2) 建立多索引搜索器:
Searcher[] searchers = new SEARCHER[2];
Searchers[0] = new IndexSearcher(dir1); //搜索索引目录一
Searchers[1]= new IndexSearcher(dir2);//搜索索引目录二
Searcher searcher = new MultiSearcher(serarchers);
3) 开始查询:Hits hits = searcher.search(query);
复合查询(多种查询条件的综合查询)
Query query=MultiFieldQueryParser.parse("索引",new String[]{"title","content"},analyzer);
Query mquery=new WildcardQuery(new Term("sender","bluedavy*"));
TermQuery tquery=new TermQuery(new Term("name","jerry"));
BooleanQuery bquery=new BooleanQuery();
bquery.add(query,true,false);
bquery.add(mquery,true,false);
bquery.add(tquery,true,false);
Searcher searcher=new IndexSearcher(indexFilePath);
Hits hits=searcher.search(bquery);
for (int i = 0; i < hits.length(); i++) {
System.out.println(hits.doc(i).get("name"));
}
高级篇
Lucene
|
传统表
|
说明
|
IndexWriter
|
table
|
|
Document
|
一条记录
|
|
Field
|
每个字段
|
分为可被索引的,可切分的,不可被切分的,不可被索引的几种组合类型
|
Hits
|
RecoreSet
|
结果集
|
|
属性
|
默认值
|
说明
|
mergeFactor
|
org.apache.lucene.mergeFactor
|
10
|
控制
index
的大小和频率
,
两个作用
1.
一个段有多少
document
2.
多少个段合成一个大段
|
maxMergeDocs
|
org.apache.lucene.maxMergeDocs
|
Integer.MAX_VALUE
|
限制一个段中的
document
数目
|
minMergeDocs
|
org.apache.lucene.minMergeDocs
|
10
|
缓存在内存中的
document
数目,超过他以后会写入到磁盘
|
maxFieldLength
|
|
1000
|
一个
Field
中最大
Term
数目,超过部分忽略,不会
index
到
field
中,所以自然也就搜索不到
|
查询方式
|
说明
|
TermQuery
|
条件查询
例如:
TermQuery tquery=new TermQuery(new Term("name","jerry"));
name:
字段名
jerry:
要搜索的字符串
|
MultiTermQuery
|
多个字段进行同一关键字的查询
Query query= null;
Query =MultiFieldQueryParser.parse("
我
",new String[] {"title","content"},analyzer);
Searcher searcher=new IndexSearcher(indexFilePath); Hits hits=searcher.search(query); |
BooleanQuery
|
例如:
BooleanQuery bquery=new BooleanQuery(); bquery.add(query,true,false); bquery.add(mquery,true,false); bquery.add(tquery,true,false); Searcher searcher=new IndexSearcher(indexFilePath); Hits hits=searcher.search(bquery); |
WildcardQuery
|
语义查询(通配符查询)
例:
Query query= new WildcardQuery(new Term("sender","*davy*"));
|
PhraseQuery
|
短语查询
|
PrefixQuery
|
前缀查询
|
PhrasePrefixQuery
|
短语前缀查询
|
FuzzyQuery
|
模糊查询
|
RangeQuery
|
范围查询
|
SpanQuery
|
范围查询
|
类型
|
Analyzed
|
Indexed
|
Stored
|
说明
|
Field.Keyword(String,String/Date)
|
N
|
Y
|
Y
|
这个
Field
用来储存会直接用来检索的比如
(
编号
,
姓名
,
日期等
)
|
Field.UnIndexed(String,String)
|
N
|
N
|
Y
|
不会用来检索的信息
,
但是检索后需要显示的
,
比如
,
硬件序列号
,
文档的
url
地址
|
Field.UnStored(String,String)
|
Y
|
Y
|
N
|
大段文本内容
,
会用来检索
,
但是检索后不需要从
index
中取内容
,
可以根据
url
去
load
真实的内容
|
Field.Text(String,String)
|
Y
|
Y
|
Y
|
检索
,
获取都需要的内容
,
直接放
index
中
,
不过这样会增大
index
|
Field.Text(String,Reader)
|
Y
|
Y
|
N
|
如果是一个
Reader, lucene
猜测内容比较多
,
会采用
Unstored
的策略
.
|