1 概述
1.1 查询对象
对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name:lucene”表示查询Field的name为“lucene”的文档信息。
可通过两种方法创建查询对象:
1)使用Lucene提供Query子类
Query是一个抽象类,lucene提供了很多查询对象,比如TermQuery项精确查询,NumericRangeQuery数字范围查询等。
如下代码:
Query query = new TermQuery(new Term("name", "lucene"));
2)使用QueryParse解析查询表达式
QueryParse会将用户输入的查询表达式解析成Query对象实例。
如下代码:
QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
Query query =queryParser.parse("name:lucene");
1.2 公共类抽取
//IndexReader IndexSearcher
public IndexSearcher getIndexSearcher() throws Exception{
// 第一步:创建一个Directory对象,也就是索引库存放的位置。
Directory directory = FSDirectory.open(new File("F:\\lucene\\index"));// 磁盘
// 第二步:创建一个indexReader对象,需要指定Directory对象。
IndexReader indexReader = DirectoryReader.open(directory);
// 第三步:创建一个indexsearcher对象,需要指定IndexReader对象
return new IndexSearcher(indexReader);
}
//执行查询的结果
public void printResult(IndexSearcher indexSearcher,Queryquery)throws Exception{
// 第五步:执行查询。
TopDocs topDocs = indexSearcher.search(query, 10);
// 第六步:返回查询结果。遍历查询结果并输出。
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDocscoreDoc : scoreDocs) {
int doc = scoreDoc.doc;
Document document =indexSearcher.doc(doc);
// 文件名称
String fileName = document.get("fileName");
System.out.println(fileName);
// 文件内容
String fileContent = document.get("fileContent");
System.out.println(fileContent);
// 文件大小
String fileSize = document.get("fileSize");
System.out.println(fileSize);
// 文件路径
String filePath = document.get("filePath");
System.out.println(filePath);
System.out.println("------------");
}
}
2 Api使用(二选一)
2.1 使用query的子类查询
2.1.1 MatchAllDocsQuery(查询所有)
使用MatchAllDocsQuery查询索引目录中的所有文档
//查询所有
@Test
public void testMatchAllDocsQuery() throws Exception{
IndexSearcher indexSearcher =getIndexSearcher();
Query query = new MatchAllDocsQuery();
System.out.println(query);
printResult(indexSearcher, query);
//关闭资源
indexSearcher.getIndexReader().close();
}
2.1.2 TermQuery(条件查询/项查询)
TermQuery,通过项查询,TermQuery不使用分析器所以建议匹配不分词的Field域查询,比如订单号、分类ID号等。
指定要查询的域和要查询的关键词。
//使用Termquery查询
@Test
public void testTermQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
//创建查询对象
Query query = new TermQuery(new Term("content", "lucene"));
//执行查询
TopDocs topDocs = indexSearcher.search(query, 10);
//共查询到的document个数
System.out.println("查询结果总数量:" + topDocs.totalHits);
//遍历查询结果
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("filename"));
//System.out.println(document.get("content"));
System.out.println(document.get("path"));
System.out.println(document.get("size"));
}
//关闭indexreader
indexSearcher.getIndexReader().close();
}
2.1.3 NumericRangeQuery(根据数值范围查询)
可以根据数值范围查询。//参数:1.域名 2.最小值 3.最大值 4.是否包含最小值 5.是否包含最大值
//根据数值范围查询
@Test
public void testNumericRangeQuery() throws Exception{
IndexSearcher indexSearcher =getIndexSearcher();
Query query = NumericRangeQuery.newLongRange("fileSize", 47L, 200L, false, true);
System.out.println(query);
printResult(indexSearcher, query);
//关闭资源
indexSearcher.getIndexReader().close();
}
2.1.4 BooleanQuery(组合查询)
可以组合查询条件。
//可以组合查询条件
@Test
public void testBooleanQuery() throws Exception{
IndexSearcher indexSearcher =getIndexSearcher();
//创建一个布尔查询对象
BooleanQuery booleanQuery = new BooleanQuery();
//创建第一个查询条件
Query query1 = new TermQuery(new Term("fileName","apache"));
Query query2 = new TermQuery(newTerm("fileName","lucene"));
// select * fromuser where id =1 or name = 'safdsa'
//组合查询条件
booleanQuery.add(query1, Occur.MUST);
booleanQuery.add(query2, Occur.SHOULD);
System.out.println(booleanQuery);
printResult(indexSearcher,booleanQuery);//执行查询
//关闭资源
indexSearcher.getIndexReader().close();
}
Occur.MUST:必须满足此条件,相当于and
Occur.SHOULD:应该满足,但是不满足也可以,相当于or
Occur.MUST_NOT:必须不满足。相当于not
2.2 使用queryparser查询
2.2.1 概念
通过QueryParser也可以创建Query,QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询。Query对象执行的查询语法可通过System.out.println(query);查询。
需要使用到分析器。建议创建索引时使用的分析器和查询索引时使用的分析器要一致。
需要加入queryParser依赖的jar包。
2.2.2 程序实现
//条件解释的对象查询
@Test
public void testQueryParser() throws Exception{
IndexSearcher indexSearcher =getIndexSearcher();
//创建queryparser对象
//参数1: 默认查询的域
//参数2:采用的分析器
QueryParser queryParser = new QueryParser("fileName",newIKAnalyzer());
// *:* 域:值
Query query = queryParser.parse("fileName:lucene is apache ORfileContent:lucene is apache");
printResult(indexSearcher, query);
//关闭资源
indexSearcher.getIndexReader().close();
}
2.2.3 查询语法
1、基础的查询语法,关键词查询:
域名+“:”+搜索的关键字
例如:content:java
2、范围查询
域名+“:”+[最小值 TO 最大值]
例如:size:[1 TO 1000]
范围查询在lucene中支持数值类型,不支持字符串类型。在solr中支持字符串类型。
3、组合条件查询
1)+条件1 +条件2:两个条件之间是并且的关系and
例如:+filename:apache+content:apache
2)+条件1 条件2:必须满足第一个条件,应该满足第二个条件
例如:+filename:apache content:apache
3)条件1 条件2:两个条件满足其一即可。
例如:filename:apachecontent:apache
4)-条件1 条件2:必须不满足条件1,要满足条件2
例如:-filename:apachecontent:apache
第二种写法:
条件1 AND 条件2
条件1 OR 条件2
条件1 NOT 条件2
2.2.4 MultiFieldQueryParser
可以指定多个默认搜索域
//条件解析的对象查询 多个默念域
@Test
public void testMultiFieldQueryParser() throws Exception{
IndexSearcher indexSearcher =getIndexSearcher();
String[] fields = {"fileName","fileContent"};
//参数1:默认查询的域
//参数2:采用的分析器
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields,new IKAnalyzer());
// *:* 域:值
Query query = queryParser.parse("lucene is apache");
printResult(indexSearcher, query);
//关闭资源
indexSearcher.getIndexReader().close();
}