这里首先介绍一下基本的query:
1,最普通的TermQuery
TermQuery最普通, 用Term t=new Term("contents","cap"); new TermQuery(t)就可以构造
TermQuery把查询条件视为一个key, 要求和查询内容完全匹配,比如Field.Keyword类型就可以使用TermQuery
2,RangeQuery
RangeQuery表示一个范围的搜索条件,RangeQuery query = new RangeQuery(begin, end, included);
最后一个boolean值表示是否包含边界条件本身, 用字符表示为"[begin TO end]" 或者"{begin TO end}"
3,PrefixQuery
顾名思义,就是表示以某某开头的查询, 字符表示为"something*"
4,BooleanQuery
这个是一个组合的Query,你可以把各种Query添加进去并标明他们的逻辑关系,添加条件用
public void add(Query query, boolean required, boolean prohibited)
方法, 后两个boolean变量是标示AND OR NOT三种关系 字符表示为" AND OR NOT" 或 "+ -" ,一个BooleanQuery中可以添加多个Query, 如果超过setMaxClauseCount(int)的值(默认1024个)的话,会抛出TooManyClauses错误.
5,PhraseQuery
表示不严格语句的查询,比如"red pig"要匹配"red fat pig","red fat big pig"等,PhraseQuery所以提供了一个setSlop()参数,在查询中,lucene会尝试调整单词的距离和位置,这个参数表示可以接受调整次数限制,如果实际的内容可以在这么多步内调整为完全匹配,那么就被视为匹配.在默认情况下slop的值是0, 所以默认是不支持非严格匹配的, 通过设置slop参数(比如"red pig"匹配"red fat pig"就需要1个slop来把pig后移动1位),我们可以让lucene来模糊查询. 值得注意的是,PhraseQuery不保证前后单词的次序,在上面的例子中,"pig red"需要2个slop,也就是如果slop如果大于等于2,那么"pig red"也会被认为是匹配的.
6,WildcardQuery
使用?和*来表示一个或多个字母比如wil*a可以匹配 wilda ,wilba ,wilxaaaa...,值得注意的是,在wildcard中,只要是匹配上的纪录,他们的相关度都是一样的,比如wilxaaaa和wilda的对于wil*a的相关度就是一样的.
7,FuzzyQuery
这个Query对中文没有什么用处,他能模糊匹配英文单词(前面的都是词组),比如fuzzy和wuzzy他们可以看成类似, 对于英文的各种时态变化和复数形式,这个FuzzyQuery还算有用,匹配结果的相关度是不一样的.字符表示为 "fuzzy~"
注意上面WildcardQuery类,在网上有很多资料在介绍WildcardQuery时,比如:http://www.ibm.com/developerworks/cn/web/wa-lucene2/
中就写到:
如果你想查询 Teach, Teacher 和 Teaching,你就可以使用查询语句 “Teach*”。下面代码 显示了通配符查询的过程。
1 public void testWildcardSearch(String indexDirectory)throws Exception{
2 Directory dir = FSDirectory.getDirectory(indexDirectory,false);
3 IndexSearcher indexSearcher = new IndexSearcher(dir);
4 String[] searchWords = {"tex*", "tex?", "?ex*"};
5 Query query;
6 for(int i = 0; i < searchWords.length; i++){
7 query = new WildcardQuery(new Term("title",searchWords[i]));
8 Hits results = indexSearcher.search(query);
9 System.out.println(results.length() + "search results for query " + searchWords[i]);
10 }
11 }
都给人以误解(当然上面代码这样写是没错的、可以执行的),比如像GOOGLE一样在查询框中用"Teach*"时查询会实例化WildcardQuery类,而在《Lucene IN ACTION》书中关于解析查询表达式:QueryParser的说明中写到了通配符和前缀查询关系:
如果某个项包含了一个星号或问号,该项就会看作是进行通配符查询的一个WildcardQuery对象。而当查询项仅在项的末尾有一个星号时,QueryParser会将它优化为前缀查询的 PrefixQuery对象。不管是前缀查询,还是通配符查询,其对象都会被默认地转换为小写形式,不过该转换行为也是可以控制的。
如果要关闭自动的小写转换功能,就一定要自己创建QueryParser实例,而不能只通过静态的parse()方法。当通配符位于查询项的开头时,不能使用QueryParser进行解析;但由API的构造函数创建的Wildcard对象,则允许查询项以通配符开头(但这以损失查询性能为代价)。
所以在这里给刚上路的新手一点说明。
---------------------------------------------------------------------------------------------------------------------------------
说人之短,乃护己之短。夸己之长,乃忌人之长。皆由存心不厚,识量太狭耳。能去此弊,可以进德,可以远怨。
http://www.blogjava.net/szhswl
------------------------------------------------------------------------------------------------------ ----------------- ---------
posted on 2007-12-18 11:43
宋针还 阅读(1345)
评论(0) 编辑 收藏