基本流程
1、 初始化IndexSearcher :Searcher searcher = new IndexSearcher(indexDir);//indexDir为索引存放路径
2、 生成Query对象: QueryParser类的parse()方法返回Query类形对象
3、 使用search(Query)方法,开始搜索,并返回Hits对象
4、 使用Hits对象的方法检索结果:
length();//结果总数量
doc(int n);//返回第n个文档;Document对象
id(int n);//第n个文档的内部ID
score(n);//第n个文档的分值,用于排序
例子:
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);