Lucene 查询中有两种查询方式:使用字符串查询[可以使用特定的查询语法] 使用对像查询[查询对象,通过它的子类来实现]
Query 查询:TermQuery 关键字查询 RangeQuery 范围查询 WildcardQuery 短语查询 BooleanQuery 布尔查询
private String indexPath="D://ec_pj//LuceneDemo1//luceneIndex";
private Analyzer analyzer=new MMAnalyzer();
@Test
public void test(){
}
@Test
public void testTermQuery()throws Exception{
//Term term=new Term("content","老婆");
//Term term=new Term("content","KEY"); //关键词中没有大写,均为小写字符
Term term=new Term("content","key");
Query query=new TermQuery(term);
List<Document> resultList=search(query);
for (Document doc : resultList) {
System.out.println(doc.get("name"));
System.out.println(doc.get("content"));
System.out.println(doc.get("size"));
System.out.println(doc.get("path"));
}
}
@Test
public void testRangeQuery()throws Exception{
Term lowerTerm=new Term("size",NumberTools.longToString(70)); //范围大小是按字符串比较大小的
Term upperTerm=new Term("size",NumberTools.longToString(2045));
//NumberTools.longToString(200) 使用工具类,转为化字符串采用36进制存储 采用工具类时,创建索引时也要使用该工具类
Query query=new RangeQuery(lowerTerm, upperTerm, true); //boolean 是否包含边界
System.out.println(query.toString());
List<Document> resultList=search(query);
for (Document doc : resultList) {
System.out.println(doc.get("name"));
System.out.println(doc.get("content"));
System.out.println(doc.get("size"));
System.out.println(doc.get("path"));
}
}
同样的日期的处理也有对应的工具类:DateTools
DateTools.dateToString(new Date(), Resolution.DAY)
/**
* 短语查询 中间可以隔几个词
* @throws Exception
*/
@Test
public void testPhraseQuery()throws Exception{
PhraseQuery query=new PhraseQuery();
// query.add(new Term("content","snta"),1);
// query.add(new Term("content","love"),3);
query.add(new Term("content","code"));
query.add(new Term("content","love"));
//设置两个关键字中间可以隔多少个单键词
query.setSlop(5); //会覆盖前面的设置,如果是0代表位置精确匹配
List<Document> resultList=search(query);
printResult(resultList);
}
/**
* 可以将几个查询组合起来,查询所有条件都满足或部分满足或都不满足的结果
* @throws Exception
* MUST 和MUST取查询子句的交集
* MUST 和 MUST_NOT:包含MUST不包含MUST_NOT的查询结果
* SHOULD和SHOULD表示或关系,所有查询子句的并集
*
* 使用时注意:
* MUST和SHOULD,些时SHOULD无意义,结果为MUST子句的检索结果
* MUST_NOT和MUST_NOT,无意义,检索无结果
* MUST_NOT和SHOULD,些时SHOULD相当于MUST,结果同MUST和MUST_NOT
* 单独使用SHOULD ,结果相当于MUST
* 单独使用MUST_NOT,无意义,检索无结果
*/
@Test
public void testBooleanQuery()throws Exception{
Term term=new Term("content","snt?");
Query query1=new WildcardQuery(term);
PhraseQuery query2=new PhraseQuery();
query2.add(new Term("content","code"));
query2.add(new Term("content","love"));
query2.setSlop(5);
BooleanQuery query=new BooleanQuery();
query.add(query1, Occur.MUST_NOT);
query.add(query2, Occur.SHOULD);
List<Document> resultList=search(query);
printResult(resultList);
}
查询语法:content:李乐平 字段:关键字 content:key
范围查询:字段:[100000 TO 200000] 格式 size:(2 to 4) size:[2,4]
通配符查询: name:lov?
短语查询: content:"? 我 ? ? ? 喜欢 " content:"我 喜欢"~2 中间至多想隔两个关键字
布尔查询: +content:snt? -content:"code love"~5 +代表必须的 -必须排除 MUST和MUST_NOT
如果:SHOULD SHOULD 没有符号 content:snt? content:"code love"~5
AND OR NOT
@Test
public void testQueryString()throws Exception{
// String query="content:snt? AND content:/"code love/"~5";
// String query="content:snt? OR content:/"code love/"~5";
String query="content:snt? NOT content:/"code love/"~5";
//多个条件组合可以加括号
List<Document> resultList=search(query);
printResult(resultList);
}
搜索结果的排序 默认根据相关度排序 也可以按照指定的规则排序
可以影响相关度排序,指定Field的boost属性[默认值为1.0f] 指定Document的boost 值
在检索前指定上面的boost值 在创建索引时指定boost值
Document doc=File2DocumentUtils.file2Document(filePath);
//doc.setBoost(2f);
Document doc1=File2DocumentUtils.file2Document(filePath1);
//doc1.setBoost(5f);
IndexWriter iw=new IndexWriter(FSDirectory.getDirectory(new File(indexPath)),analyzer,true,MaxFieldLength.LIMITED);
iw.addDocument(doc);
iw.addDocument(doc1);
iw.close();
//boosts.put("name", 3f);
//boosts.put("document", 2f);
QueryParser queryParser=new MultiFieldQueryParser(new String[]{"name","content"},analyzer,boosts);
查询search() 方法最后一个参数是个排序条件
Sort sort=new Sort();
sort.setSort("size", true); //如果为true,降序
TopDocs topdocs=is.search(query, null, 10000,sort);
过滤器 Filter 过滤器的使用会对检索性能产生很大影响
Filter filter=new RangeFilter("size", NumberTools.longToString(200), NumberTools.longToString(2550), true, true);
TopDocs topdocs=is.search(query, filter, 10000,sort);