在Lucene中实现组合查询的方法很多,我目前用过的方法有三种,使用MultiFieldQueryParser,使用filter,使用boolean query。
1.使用MultiFieldQueryParser
构建parser的时候使用MultiFieldQueryParser,查询时便可以同时在索引的多个域中搜索关键字。适用情况举例:将文章的标题和内容分别存在索引的不同field中,但是希望同时在两个field中查找同一个关键字。假定这两个field为“name”和“content”,语句如下:
MultiFieldQueryParser parser=new MultiFieldQueryParser(new String[]{"name","content"},new StandardAnalyzer());
构造query时使用这个parser即可实现同时在两个field中查询:
Query query=parser.parse(keyword);
2.使用filter
使用QueryFilter实现在搜索结果中再查找。关键语句如下:
Query query = queryParser.parse(keyword2.trim());
Query oldQuery = queryParser.parse(keyword1.trim());
QueryFilter oldFilter = new QueryFilter(oldQuery);
CachingWrapperFilter filter = new CachingWrapperFilter(oldFilter);
keyword1和keyword2 是两个关键字,其先后顺序对于搜索结果集没有影响。使用searcher时同时传入query和filter即可。
例如,搜索关键字是“博客”、”wauwa“,那么搜索出来的结果是同时包含”博客“和”wauwa“的文章。
3.使用boolean query
上述两种方法实现的功能都不够强大,实现的是较为简单的组合。第一种是多个field的组合,第二种是多个关键字的组合。使用boolean query 可以实现比较复杂的组合查询,实现也比较简单。
简单来说,boolean query实现了将针对不同关键字,不同field的query组合在一起。
比如,存放文件内容的field是”content“,现在需要在content中查找同时包含多个关键字的文章,关键字存在String 数组strb[i]中,实现语句如下:
// 构造一个布尔查询
BooleanQuery Bquery = new BooleanQuery();
for(int i=0;i<keywordnum;i++){
Query query=parser.parse(strb[i]);
// 添加子查询
Bquery.add(query, BooleanClause.Occur.MUST);
}
先构造一个布尔查询,在为每个关键字创建一个query,再把这个query添加到布尔查询中,查询时向searcher传入Bquery即可。
此处的query可以根据需要,查各种field,各种关键字,都可以,boolean query中可以添加的query数目极限是1024条,但是网络上有一些资料说超过一定数目但未达1024条时会提示clause过多。
BooleanClause.Occur.MUST中的MUST表示此条件必须满足,上一段代码里,全都是MUST,说明针对不同query的搜索结果集取交集。除了MUST,还可以设置为MUST_NOT,SHOULD,这两者都很好理解,分别表示条件必须不满足和条件可满足。不同的条件要求组合,可以实现结果集之间的并、交等组合。