搜索
對(duì)要搜索的信息創(chuàng)建Query查詢對(duì)象,Lucene會(huì)根據(jù)Query查詢對(duì)象生成最終的查詢語法,類似關(guān)系數(shù)據(jù)庫(kù)Sql語法一樣Lucene也有自己的查詢語法,比如:“name:lucene”表示查詢Field的name為“l(fā)ucene”的文檔信息。
可通過兩種方法創(chuàng)建查詢對(duì)象:
使用Lucene提供Query子類
Query是一個(gè)抽象類,lucene提供了很多查詢對(duì)象,比如TermQuery項(xiàng)精確查詢,NumericRangeQuery數(shù)字范圍查詢等。
如下代碼:
Query query = new TermQuery(new Term("name", "lucene"));使用QueryParse解析查詢表達(dá)式
QueryParse會(huì)將用戶輸入的查詢表達(dá)式解析成Query對(duì)象實(shí)例。
如下代碼:
QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
Query query = queryParser.parse("name:lucene");
各種查詢
TermQuery:
根據(jù)詞進(jìn)行搜索(只能從文本中進(jìn)行搜索)
TermQuery,通過項(xiàng)查詢,TermQuery不使用分析器所以建議匹配不分詞的Field域查詢,比如訂單號(hào)、分類ID號(hào)等。指定要查詢的域和要查詢的關(guān)鍵詞。
@Test
public void testIndexTermQuery() throws Exception{
//創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
Analyzer analyzer = new IKAnalyzer();
//指定索引和文檔的目錄
Directory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
IndexReader indexReader = IndexReader.open(dir);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//創(chuàng)建詞元:就是詞,
Term t = new Term("fileName" , "apache");
//使用TermQuery查詢,根據(jù)term對(duì)象進(jìn)行查詢
TermQuery query = new TermQuery(t);
//搜索:第一個(gè)參數(shù)為查詢語句對(duì)象, 第二個(gè)參數(shù):指定顯示多少條
TopDocs topdocs = indexSearcher.search(query , 10);
//一共搜索到多少條記錄
System.out.println("=====count=====" + topdocs.totalHits);
//從搜索結(jié)果對(duì)象中獲取結(jié)果集
ScoreDoc[] scoreDocs = topdocs.scoreDocs;
for(ScoreDoc scoreDoc : scoreDocs){
//獲取docID
int docID = scoreDoc.doc;
//通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
Document document = indexReader.document(docID);
//get域名可以取出值 打印
System.out.println("fileName:" + document.get("fileName"));
System.out.println("fileSize:" + document.get("fileSize"));
System.out.println("============================================================");
}
}
QueryParser:
根據(jù)域名進(jìn)行搜索,可以設(shè)置默認(rèn)搜索域,推薦使用. (只能從文本中進(jìn)行搜索)
通過QueryParser也可以創(chuàng)建Query,QueryParser提供一個(gè)Parse方法,此方法可以直接根據(jù)查詢語法來查詢。Query對(duì)象執(zhí)行的查詢語法可通過System.out.println(query);查詢,需要使用到分析器。建議創(chuàng)建索引時(shí)使用的分析器和查詢索引時(shí)使用的分析器要一致。
1 , 需要加入queryParser依賴的jar包。
\lib\lucene-queryparser-4.10.3.jar
2,實(shí)現(xiàn)
private String searchField = "fileName";
private String searchWord = "1.create web page.txt";
@Test
public void testIndexSearch() throws Exception{
//創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
Analyzer analyzer = new IKAnalyzer();
//指定索引和文檔的目錄
Directory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
//索引和文檔的讀取對(duì)象
DirectoryReader indexReader = IndexReader.open(dir);
//創(chuàng)建索引的搜索對(duì)象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
/**
* 默認(rèn)搜索域作用:如果搜索語法中指定域名從指定域中搜索,如果搜索時(shí)只寫了查詢關(guān)鍵字,則從默認(rèn)搜索域中進(jìn)行搜索
* 第一個(gè)參數(shù):默認(rèn)搜索域,
* 第二個(gè)參數(shù):分詞器
*/
QueryParser queryParser = new QueryParser("fileContent" , analyzer);
// Query query = queryParser.parse("apache");//從默認(rèn)域搜索
Query query = queryParser.parse(searchField+":"+searchWord);//從指定域搜索
/**
* 搜索:
* 第一個(gè)參數(shù)為查詢語句對(duì)象
* 第二個(gè)參數(shù):指定顯示多少條
*/
TopDocs topDocs = indexSearcher.search(query, 10);
//一共搜索到多少條記錄
System.out.println("=====count======"+topDocs.totalHits);
//從搜索結(jié)果對(duì)象中獲取結(jié)果集
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs){
//獲取docId
int docId = scoreDoc.doc;
//通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
Document document = indexReader.document(docId);
System.out.println("fileName="+document.get("fileName"));
System.out.println("fileSize="+document.get("fileSize"));
System.out.println("=====================================");
}
}
NumericRangeQuery:
從數(shù)值范圍進(jìn)行搜索
@Test
public void testNumericRangeQuery() throws Exception{
//創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
Analyzer analyzer = new IKAnalyzer();
//指定索引和文檔的目錄
FSDirectory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
IndexReader indexReader = IndexReader.open(dir);
//創(chuàng)建索引的搜索對(duì)象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//根據(jù)數(shù)字范圍查詢
//查詢文件大小,大于100 小于1000的文章
/**
* 第一個(gè)參數(shù):域名
* 第二個(gè)參數(shù):最小值,
* 第三個(gè)參數(shù):最大值,
* 第四個(gè)參數(shù):是否包含最小值,
* 第五個(gè)參數(shù):是否包含最大值
*/
NumericRangeQuery<Long> query = NumericRangeQuery.newLongRange("fileSize", 100L, 1000L, true, true);
//搜索:第一個(gè)參數(shù)為查詢語句對(duì)象, 第二個(gè)參數(shù):指定顯示多少條
TopDocs topdocs = indexSearcher.search(query, 10);
//從搜索結(jié)果對(duì)象中獲取結(jié)果集
ScoreDoc[] scoreDocs = topdocs.scoreDocs;
for(ScoreDoc scoreDoc : scoreDocs){
//獲取docID
int docID = scoreDoc.doc;
//通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
Document document = indexReader.document(docID);
//get域名可以取出值 打印
System.out.println("fileName:" + document.get("fileName"));
System.out.println("fileSize:" + document.get("fileSize"));
System.out.println("============================================================");
}
}
BooleanQuery:
- 組合查詢,可以設(shè)置組合條件,not and or.從多個(gè)域中進(jìn)行查詢
- must相當(dāng)于and關(guān)鍵字,是并且的意思
- should,相當(dāng)于or關(guān)鍵字或者的意思
- must_not相當(dāng)于not關(guān)鍵字, 非的意思
- 注意:單獨(dú)使用must_not 或者 獨(dú)自使用must_not沒有任何意義
@Test
public void testBooleanQuery() throws Exception{
//創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
Analyzer analyzer = new IKAnalyzer();
//指定索引和文檔的目錄
FSDirectory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
IndexReader indexReader = IndexReader.open(dir);
//創(chuàng)建索引的搜索對(duì)象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//布爾查詢,就是可以根據(jù)多個(gè)條件組合進(jìn)行查詢
//文件名稱包含apache的,并且文件大小大于等于100 小于等于1000字節(jié)的文章
BooleanQuery query = new BooleanQuery();
//創(chuàng)建詞元:就是詞,
Term t = new Term("fileName" , "apache");
//使用TermQuery查詢,根據(jù)term對(duì)象進(jìn)行查詢
TermQuery termQuery = new TermQuery(t);
//根據(jù)數(shù)字范圍查詢
//查詢文件大小,大于100 小于1000的文章
NumericRangeQuery<Long> numQuery = NumericRangeQuery.newLongRange("fileSize", 100L, 1000L, true, true);
//Occur是邏輯條件
//must相當(dāng)于and關(guān)鍵字,是并且的意思
//should,相當(dāng)于or關(guān)鍵字或者的意思
//must_not相當(dāng)于not關(guān)鍵字, 非的意思
//注意:單獨(dú)使用must_not 或者 獨(dú)自使用must_not沒有任何意義
query.add(termQuery , BooleanClause.Occur.MUST);
query.add(numQuery , BooleanClause.Occur.MUST);
TopDocs topdocs = indexSearcher.search(query, 10);
//從搜索結(jié)果對(duì)象中獲取結(jié)果集
ScoreDoc[] scoreDocs = topdocs.scoreDocs;
for(ScoreDoc scoreDoc : scoreDocs){
//獲取docID
int docID = scoreDoc.doc;
//通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
Document document = indexReader.document(docID);
//get域名可以取出值 打印
System.out.println("fileName:" + document.get("fileName"));
System.out.println("fileSize:" + document.get("fileSize"));
System.out.println("============================================================");
}
}
MatchAllDocsQuery:
查詢出所有文檔
@Test
public void testMathAllQuery() throws Exception{
//創(chuàng)建分詞器(創(chuàng)建索引和所有時(shí)所用的分詞器必須一致)
Analyzer analyzer = new IKAnalyzer();
//查詢所有文檔
MatchAllDocsQuery query = new MatchAllDocsQuery();
//指定索引和文檔的目錄
Directory dir = FSDirectory.open(new File("E:\\dic"));
//索引和文檔的讀取對(duì)象
IndexReader indexReader = IndexReader.open(dir);
//創(chuàng)建索引的搜索對(duì)象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//搜索:第一個(gè)參數(shù)為查詢語句對(duì)象, 第二個(gè)參數(shù):指定顯示多少條
TopDocs topdocs = indexSearcher.search(query, 5);
//一共搜索到多少條記錄
System.out.println("=====count=====" + topdocs.totalHits);
//從搜索結(jié)果對(duì)象中獲取結(jié)果集
ScoreDoc[] scoreDocs = topdocs.scoreDocs;
for(ScoreDoc scoreDoc : scoreDocs){
//獲取docID
int docID = scoreDoc.doc;
//通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
Document document = indexReader.document(docID);
//get域名可以取出值 打印
System.out.println("fileName:" + document.get("fileName"));
System.out.println("fileSize:" + document.get("fileSize"));
System.out.println("============================================================");
}
}
MultiFieldQueryParser:
可以從多個(gè)域中進(jìn)行查詢,只有這些域中有關(guān)鍵詞的存在就查詢出來.
@Test
public void testMultiFieldQueryParser() throws Exception{
//創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
Analyzer analyzer = new IKAnalyzer();
//指定索引和文檔的目錄
FSDirectory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
IndexReader indexReader = IndexReader.open(dir);
//創(chuàng)建索引的搜索對(duì)象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
String[] fields = {"fileName" , "fileContext"};
//從文件名稱和文件內(nèi)容中查詢,只有含有apache的就查出來
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields , analyzer);
//輸入需要搜索的關(guān)鍵字
Query query = queryParser.parse("apache");
//搜索:第一個(gè)參數(shù)為查詢語句對(duì)象, 第二個(gè)參數(shù):指定顯示多少條
TopDocs topdocs = indexSearcher.search(query, 10);
//從搜索結(jié)果對(duì)象中獲取結(jié)果集
ScoreDoc[] scoreDocs = topdocs.scoreDocs;
for(ScoreDoc scoreDoc : scoreDocs){
//獲取docID
int docID = scoreDoc.doc;
//通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
Document document = indexReader.document(docID);
//get域名可以取出值 打印
System.out.println("fileName:" + document.get("fileName"));
System.out.println("fileSize:" + document.get("fileSize"));
System.out.println("============================================================");
}
}