轉載自:http://book.51cto.com/art/200805/72684.htm
11.4 構建各種Query
搜尋流程中的第二步就是構建一個Query。下面就來介紹Query及其構建。
當使用者輸入一個關鍵字,搜尋引擎接收到後,並不是立刻就將它放入後台開始進行關鍵字的檢索,而應當首先對這個關鍵字進行一定的分析和處理,使之成為一種後台可以理解的形式,只有這樣,才能提高檢索的效率,同時檢索出更加有效結果。那麼,在Lucene中,這種處理,其實就是構建一個Query對象。
就Query對象本身言,它只是Lucene的search包中的一個抽象類別,這個抽象類別有許多子類,代表了不同類型的檢索。如常見的TermQuery就是將一個簡單的關鍵字進行封裝後的對象,類似的還有BooleanQuery,即布爾型的尋找。
IndexSearcher對象的search方法中總是需要一個Query對象(或是Query子類的對象),本節就來介紹各種Query類。
11.4.1 按詞條搜尋—TermQuery
TermQuery是最簡單、也是最常用的Query。TermQuery可以理解成為“詞條搜尋”,在搜尋引擎中最基本的搜尋就是在索引中搜尋某一詞條,而TermQuery就是用來完成這項工作的。
在Lucene中詞條是最基本的搜尋單位,從本質上來講一個詞條其實就是一個名/值對。只不過這個“名”是欄位名,而“值”則表示欄位中所包含的某個關鍵字。
要使用TermQuery進行搜尋首先需要構造一個Term對象,範例程式碼如下:
Term aTerm = new Term("contents", "java");
然後使用aTerm對象為參數來構造一個TermQuery對象,代碼設定如下:
Query query = new TermQuery(aTerm);
這樣所有在“contents”欄位中包含有“java”的文檔都會在使用TermQuery進行查詢時作為符合查詢條件的結果返回。
下面就通過代碼11.4來介紹TermQuery的具體實現過程。
代碼11.4 TermQueryTest.java
package ch11;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
public class TermQueryTest
{
public static void main(String[] args) throws Exception
{
//產生Document對象
Document doc1 = new Document();
//添加“name”欄位的內容
doc1.add(Field.Text("name", "word1 word2 word3"));
//添加“title”欄位的內容
doc1.add(Field.Keyword("title", "doc1"));
//產生索引書寫器
IndexWriter writer = new IndexWriter("c:\\index", new StandardAnalyzer(), true);
//將文檔添加到索引中
writer.addDocument(doc1);
//關閉索引
writer.close();
//產生查詢對象query
Query query = null;
//產生hits結果對象,儲存返回的檢索結果
Hits hits = null;
//產生檢索器
IndexSearcher searcher = new IndexSearcher("c:\\index");
// 構造一個TermQuery對象
query = new TermQuery(new Term("name","word1"));
//開始檢索,並返回檢索結果到hits中
hits = searcher.search(query);
//輸出檢索結果中的相關資訊
printResult(hits, "word1");
// 再次構造一個TermQuery對象,只不過查詢的欄位變成了"title"
query = new TermQuery(new Term("title","doc1"));
//開始第二次檢索,並返回檢索結果到hits中
hits = searcher.search(query);
//輸出檢索結果中的相關資訊
printResult(hits, "doc1");
}
public static void printResult(Hits hits, String key) throws Exception
{
System.out.println("尋找 \"" + key + "\" :");
if (hits != null)
{
if (hits.length() == 0)
{
System.out.println("沒有找到任何結果");
}
else
{
System.out.println("找到" + hits.length() + "個結果");
for (int i = 0; i < hits.length(); i++)
{
Document d = hits.doc(i);
String dname = d.get("title");
System.out.print(dname + " ");
}
System.out.println();
System.out.println();
}
}
}
}
在代碼11.4中使用TermQuery進行檢索的運行結果11-8所示。
注意:欄位值是區分大小寫,因此在查詢時必須注意大小寫匹配。
從圖11-8中可以看出,代碼11.4兩次分別以“word1”和“doc1”為關鍵字進行檢索,並且都只得到了一個檢索結果。
在代碼11.4中通過構建TermQuery的對象,兩次完成了對關鍵字的尋找。兩次尋找過程中不同的是,第一次構建的TermQuery是尋找“name”這個欄位,而第二次構建的TermQuery則尋找的是“title”這個欄位。
轉載自:http://book.51cto.com/art/200805/72684.htm