Lucene实践(二)-搜索过程 (转)

基本流程
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<hits.length();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);

posted on 2008-03-05 12:05  yurow  阅读(407)  评论(0编辑  收藏  举报

导航