Lucene 是基于 Java 的全文信息檢索包,它目前是 Apache Jakarta 家族下面的一個開源項(xiàng)目。在這篇文章中,我們首先來看如何利用Lucene 實(shí)現(xiàn)高級搜索功能,然后學(xué)習(xí)如何利用 Lucene 來創(chuàng)建一個健壯的 Web 搜索應(yīng)用程序。
在本篇文章中,你會學(xué)習(xí)到如何利用 Lucene 實(shí)現(xiàn)高級搜索功能以及如何利用 Lucene 來創(chuàng)建 Web 搜索應(yīng)用程序。通過這些學(xué)習(xí),你就可以利用 Lucene 來創(chuàng)建自己的搜索應(yīng)用程序。
架構(gòu)概覽
通常一個 Web 搜索引擎的架構(gòu)分為前端和后端兩部分,就像下圖中所示。在前端流程中,用戶在搜索引擎提供的界面中輸入要搜索的關(guān)鍵詞,這里提到的用戶界面一般是一個帶有輸入框的 Web 頁面,然后應(yīng)用程序?qū)⑺阉鞯年P(guān)鍵詞解析成搜索引擎可以理解的形式,并在索引文件上進(jìn)行搜索操作。在排序后,搜索引擎返回搜索結(jié)果給用戶。在后端流程中,網(wǎng)絡(luò)爬蟲或者機(jī)器人從因特網(wǎng)上獲取 Web 頁面,然后索引子系統(tǒng)解析這些 Web 頁面并存入索引文件中。如果你想利用 Lucene 來創(chuàng)建一個 Web 搜索應(yīng)用程序,那么它的架構(gòu)也和上面所描述的類似,就如下圖中所示。
Figure 1. Web 搜索引擎架構(gòu)
利用 Lucene 實(shí)現(xiàn)高級搜索
Lucene 支持多種形式的高級搜索,我們在這一部分中會進(jìn)行探討,然后我會使用 Lucene 的 API 來演示如何實(shí)現(xiàn)這些高級搜索功能。
布爾操作符
大多數(shù)的搜索引擎都會提供布爾操作符讓用戶可以組合查詢,典型的布爾操作符有 AND, OR, NOT。Lucene 支持 5 種布爾操作符,分別是 AND, OR, NOT, 加(+), 減(-)。接下來我會講述每個操作符的用法。
- OR: 如果你要搜索含有字符 A 或者 B 的文檔,那么就需要使用 OR 操作符。需要記住的是,如果你只是簡單的用空格將兩個關(guān)鍵詞分割開,其實(shí)在搜索的時候搜索引擎會自動在兩個關(guān)鍵詞之間加上 OR 操作符。例如,“Java OR Lucene” 和 “Java Lucene” 都是搜索含有 Java 或者含有 Lucene 的文檔。
- AND: 如果你需要搜索包含一個以上關(guān)鍵詞的文檔,那么就需要使用 AND 操作符。例如,“Java AND Lucene” 返回所有既包含 Java 又包含 Lucene 的文檔。
- NOT: Not 操作符使得包含緊跟在 NOT 后面的關(guān)鍵詞的文檔不會被返回。例如,如果你想搜索所有含有 Java 但不含有 Lucene 的文檔,你可以使用查詢語句 “Java NOT Lucene”。但是你不能只對一個搜索詞使用這個操作符,比如,查詢語句 “NOT Java” 不會返回任何結(jié)果。
- 加號(+): 這個操作符的作用和 AND 差不多,但它只對緊跟著它的一個搜索詞起作用。例如,如果你想搜索一定包含 Java,但不一定包含 Lucene 的文檔,就可以使用查詢語句“+Java Lucene”。
- 減號(-): 這個操作符的功能和 NOT 一樣,查詢語句 “Java -Lucene” 返回所有包含 Java 但不包含 Lucene 的文檔。
接下來我們看一下如何利用 Lucene 提供的 API 來實(shí)現(xiàn)布爾查詢。下面代碼 顯示了如果利用布爾操作符進(jìn)行查詢的過程。
清單1:使用布爾操作符
//Test boolean operator
public void testOperator(String indexDirectory) throws Exception{
Directory dir = FSDirectory.getDirectory(indexDirectory,false);
IndexSearcher indexSearcher = new IndexSearcher(dir);
String[] searchWords = {"Java AND Lucene", "Java NOT Lucene", "Java OR Lucene",
"+Java +Lucene", "+Java -Lucene"};
Analyzer language = new StandardAnalyzer();
Query query;
for(int i = 0; i < searchWords.length; i++){
query = QueryParser.parse(searchWords[i], "title", language);
Hits results = indexSearcher.search(query);
System.out.println(results.length() + "search results for query " + searchWords[i]);
}
}
|
域搜索(Field Search)
Lucene 支持域搜索,你可以指定一次查詢是在哪些域(Field)上進(jìn)行。例如,如果索引的文檔包含兩個域,Title
和 Content
,你就可以使用查詢 “Title: Lucene AND Content: Java” 來返回所有在 Title 域上包含 Lucene 并且在 Content 域上包含 Java 的文檔。下面代碼 顯示了如何利用 Lucene 的 API 來實(shí)現(xiàn)域搜索。
清單2:實(shí)現(xiàn)域搜索
//Test field search
public void testFieldSearch(String indexDirectory) throws Exception{
Directory dir = FSDirectory.getDirectory(indexDirectory,false);
IndexSearcher indexSearcher = new IndexSearcher(dir);
String searchWords = "title:Lucene AND content:Java";
Analyzer language = new StandardAnalyzer();
Query query = QueryParser.parse(searchWords, "title", language);
Hits results = indexSearcher.search(query);
System.out.println(results.length() + "search results for query " + searchWords);
}
|
通配符搜索(Wildcard Search)
Lucene 支持兩種通配符:問號(?)和星號(*)。你可以使用問號(?)來進(jìn)行單字符的通配符查詢,或者利用星號(*)進(jìn)行多字符的通配符查詢。例如,如果你想搜索 tiny 或者 tony,你就可以使用查詢語句 “t?ny”;如果你想查詢 Teach, Teacher 和 Teaching,你就可以使用查詢語句 “Teach*”。下面代碼 顯示了通配符查詢的過程。
清單3:進(jìn)行通配符查詢
//Test wildcard search
public void testWildcardSearch(String indexDirectory)throws Exception{
Directory dir = FSDirectory.getDirectory(indexDirectory,false);
IndexSearcher indexSearcher = new IndexSearcher(dir);
String[] searchWords = {"tex*", "tex?", "?ex*"};
Query query;
for(int i = 0; i < searchWords.length; i++){
query = new WildcardQuery(new Term("title",searchWords[i]));
Hits results = indexSearcher.search(query);
System.out.println(results.length() + "search results for query " + searchWords[i]);
}
}
|
模糊查詢
Lucene 提供的模糊查詢基于編輯距離算法(Edit distance algorithm)。你可以在搜索詞的尾部加上字符 ~ 來進(jìn)行模糊查詢。例如,查詢語句 “think~” 返回所有包含和 think 類似的關(guān)鍵詞的文檔。下面代碼顯示了如果利用 Lucene 的 API 進(jìn)行模糊查詢的代碼。
清單4:實(shí)現(xiàn)模糊查詢
//Test fuzzy search
public void testFuzzySearch(String indexDirectory)throws Exception{
Directory dir = FSDirectory.getDirectory(indexDirectory,false);
IndexSearcher indexSearcher = new IndexSearcher(dir);
String[] searchWords = {"text", "funny"};
Query query;
for(int i = 0; i < searchWords.length; i++){
query = new FuzzyQuery(new Term("title",searchWords[i]));
Hits results = indexSearcher.search(query);
System.out.println(results.length() + "search results for query " + searchWords[i]);
}
}
|
范圍搜索(Range Search)
范圍搜索匹配某個域上的值在一定范圍的文檔。例如,查詢 “age:[18 TO 35]” 返回所有 age 域上的值在 18 到 35 之間的文檔。下面代碼顯示了利用 Lucene 的 API 進(jìn)行返回搜索的過程。
清單5:測試范圍搜索
//Test range search
public void testRangeSearch(String indexDirectory)throws Exception{
Directory dir = FSDirectory.getDirectory(indexDirectory,false);
IndexSearcher indexSearcher = new IndexSearcher(dir);
Term begin = new Term("birthDay","20000101");
Term end = new Term("birthDay","20060606");
Query query = new RangeQuery(begin,end,true);
Hits results = indexSearcher.search(query);
System.out.println(results.length() + "search results is returned");
}
|
在 Web 應(yīng)用程序中集成 Lucene
接下來我們開發(fā)一個 Web 應(yīng)用程序利用 Lucene 來檢索存放在文件服務(wù)器上的 HTML 文檔。在開始之前,需要準(zhǔn)備如下環(huán)境:
- Eclipse 集成開發(fā)環(huán)境
- Tomcat 5.0
- Lucene Library
- JDK 1.5
這個例子使用 Eclipse 進(jìn)行 Web 應(yīng)用程序的開發(fā),最終這個 Web 應(yīng)用程序跑在 Tomcat 5.0 上面。在準(zhǔn)備好開發(fā)所必需的環(huán)境之后,我們接下來進(jìn)行 Web 應(yīng)用程序的開發(fā)。
1、創(chuàng)建一個動態(tài) Web 項(xiàng)目
- 在 Eclipse 里面,選擇 File > New > Project,然后再彈出的窗口中選擇動態(tài) Web 項(xiàng)目,如下圖所示。
圖二:創(chuàng)建動態(tài)Web項(xiàng)目
- 在創(chuàng)建好動態(tài) Web 項(xiàng)目之后,你會看到創(chuàng)建好的項(xiàng)目的結(jié)構(gòu),如下圖所示,項(xiàng)目的名稱為 sample.dw.paper.lucene。
圖三:動態(tài) Web 項(xiàng)目的結(jié)構(gòu)
2. 設(shè)計(jì) Web 項(xiàng)目的架構(gòu)
在我們的設(shè)計(jì)中,把該系統(tǒng)分成如下四個子系統(tǒng):
- 用戶接口: 這個子系統(tǒng)提供用戶界面使用戶可以向 Web 應(yīng)用程序服務(wù)器提交搜索請求,然后搜索結(jié)果通過用戶接口來顯示出來。我們用一個名為 search.jsp 的頁面來實(shí)現(xiàn)該子系統(tǒng)。
- 請求管理器: 這個子系統(tǒng)管理從客戶端發(fā)送過來的搜索請求并把搜索請求分發(fā)到搜索子系統(tǒng)中。最后搜索結(jié)果從搜索子系統(tǒng)返回并最終發(fā)送到用戶接口子系統(tǒng)。我們使用一個 Servlet 來實(shí)現(xiàn)這個子系統(tǒng)。
- 搜索子系統(tǒng): 這個子系統(tǒng)負(fù)責(zé)在索引文件上進(jìn)行搜索并把搜索結(jié)構(gòu)傳遞給請求管理器。我們使用 Lucene 提供的 API 來實(shí)現(xiàn)該子系統(tǒng)。
- 索引子系統(tǒng): 這個子系統(tǒng)用來為 HTML 頁面來創(chuàng)建索引。我們使用 Lucene 的 API 以及 Lucene 提供的一個 HTML 解析器來創(chuàng)建該子系統(tǒng)。
下圖顯示了我們設(shè)計(jì)的詳細(xì)信息,我們將用戶接口子系統(tǒng)放到 webContent 目錄下面。你會看到一個名為 search.jsp 的頁面在這個文件夾里面。請求管理子系統(tǒng)在包 sample.dw.paper.lucene.servlet
下面,類 SearchController
負(fù)責(zé)功能的實(shí)現(xiàn)。搜索子系統(tǒng)放在包 sample.dw.paper.lucene.search
當(dāng)中,它包含了兩個類,SearchManager
和 SearchResultBean
,第一個類用來實(shí)現(xiàn)搜索功能,第二個類用來描述搜索結(jié)果的結(jié)構(gòu)。索引子系統(tǒng)放在包 sample.dw.paper.lucene.index
當(dāng)中。類 IndexManager
負(fù)責(zé)為 HTML 文件創(chuàng)建索引。該子系統(tǒng)利用包 sample.dw.paper.lucene.util
里面的類 HTMLDocParser
提供的方法 getTitle
和 getContent
來對 HTML 頁面進(jìn)行解析。
圖四:項(xiàng)目的架構(gòu)設(shè)計(jì)
3. 子系統(tǒng)的實(shí)現(xiàn)
在分析了系統(tǒng)的架構(gòu)設(shè)計(jì)之后,我們接下來看系統(tǒng)實(shí)現(xiàn)的詳細(xì)信息。
- 用戶接口: 這個子系統(tǒng)有一個名為 search.jsp 的 JSP 文件來實(shí)現(xiàn),這個 JSP 頁面包含兩個部分。第一部分提供了一個用戶接口去向 Web 應(yīng)用程序服務(wù)器提交搜索請求,如下圖所示。注意到這里的搜索請求發(fā)送到了一個名為 SearchController 的 Servlet 上面。Servlet 的名字和具體實(shí)現(xiàn)的類的對應(yīng)關(guān)系在 web.xml 里面指定。
圖5:向Web服務(wù)器提交搜索請求
這個JSP的第二部分負(fù)責(zé)顯示搜索結(jié)果給用戶,如圖下圖所示:
圖6:顯示搜索結(jié)果
- 請求管理器: 一個名為
SearchController
的 servlet 用來實(shí)現(xiàn)該子系統(tǒng)。下面代碼給出了這個類的源代碼。
清單6:請求管理器的實(shí)現(xiàn)
package sample.dw.paper.lucene.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sample.dw.paper.lucene.search.SearchManager;
/**
* This servlet is used to deal with the search request
* and return the search results to the client
*/
public class SearchController extends HttpServlet{
private static final long serialVersionUID = 1L;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
String searchWord = request.getParameter("searchWord");
SearchManager searchManager = new SearchManager(searchWord);
List searchResult = null;
searchResult = searchManager.search();
RequestDispatcher dispatcher = request.getRequestDispatcher("search.jsp");
request.setAttribute("searchResult",searchResult);
dispatcher.forward(request, response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
doPost(request, response);
}
}
|
在代碼中,doPost
方法從客戶端獲取搜索詞并創(chuàng)建類 SearchManager
的一個實(shí)例,其中類 SearchManager
在搜索子系統(tǒng)中進(jìn)行了定義。然后,SearchManager
的方法 search 會被調(diào)用。最后搜索結(jié)果被返回到客戶端。
- 搜索子系統(tǒng): 在這個子系統(tǒng)中,我們定義了兩個類:
SearchManager
和 SearchResultBean
。第一個類用來實(shí)現(xiàn)搜索功能,第二個類是個JavaBean,用來描述搜索結(jié)果的結(jié)構(gòu)。下面代碼給出了類 SearchManager
的源代碼。
清單7:搜索功能的實(shí)現(xiàn)
package sample.dw.paper.lucene.search;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import sample.dw.paper.lucene.index.IndexManager;
/**
* This class is used to search the
* Lucene index and return search results
*/
public class SearchManager {
private String searchWord;
private IndexManager indexManager;
private Analyzer analyzer;
public SearchManager(String searchWord){
this.searchWord = searchWord;
this.indexManager = new IndexManager();
this.analyzer = new StandardAnalyzer();
}
/**
* do search
*/
public List search(){
List searchResult = new ArrayList();
if(false == indexManager.ifIndexExist()){
try {
if(false == indexManager.createIndex()){
return searchResult;
}
} catch (IOException e) {
e.printStackTrace();
return searchResult;
}
}
IndexSearcher indexSearcher = null;
try{
indexSearcher = new IndexSearcher(indexManager.getIndexDir());
}catch(IOException ioe){
ioe.printStackTrace();
}
QueryParser queryParser = new QueryParser("content",analyzer);
Query query = null;
try {
query = queryParser.parse(searchWord);
} catch (ParseException e) {
e.printStackTrace();
}
if(null != query >> null != indexSearcher){
try {
Hits hits = indexSearcher.search(query);
for(int i = 0; i < hits.length(); i ++){
SearchResultBean resultBean = new SearchResultBean();
resultBean.setHtmlPath(hits.doc(i).get("path"));
resultBean.setHtmlTitle(hits.doc(i).get("title"));
searchResult.add(resultBean);
}
} catch (IOException e) {
e.printStackTrace();
}
}
return searchResult;
}
}
|
在上面代碼,注意到在這個類里面有三個私有屬性。第一個是 searchWord
,代表了來自客戶端的搜索詞。第二個是 indexManager
,代表了在索引子系統(tǒng)中定義的類 IndexManager
的一個實(shí)例。第三個是 analyzer
,代表了用來解析搜索詞的解析器。現(xiàn)在我們把注意力放在方法 search
上面。這個方法首先檢查索引文件是否已經(jīng)存在,如果已經(jīng)存在,那么就在已經(jīng)存在的索引上進(jìn)行檢索,如果不存在,那么首先調(diào)用類 IndexManager
提供的方法來創(chuàng)建索引,然后在新創(chuàng)建的索引上進(jìn)行檢索。搜索結(jié)果返回后,這個方法從搜索結(jié)果中提取出需要的屬性并為每個搜索結(jié)果生成類 SearchResultBean
的一個實(shí)例。最后這些 SearchResultBean
的實(shí)例被放到一個列表里面并返回給請求管理器。
在類 SearchResultBean
中,含有兩個屬性,分別是 htmlPath
和 htmlTitle
,以及這個兩個屬性的 get 和 set 方法。這也意味著我們的搜索結(jié)果包含兩個屬性:htmlPath
和 htmlTitle
,其中 htmlPath
代表了 HTML 文件的路徑,htmlTitle
代表了 HTML 文件的標(biāo)題。
- 索引子系統(tǒng): 類
IndexManager
用來實(shí)現(xiàn)這個子系統(tǒng)。 下面代碼給出了這個類的源代碼。
清單8:索引子系統(tǒng)的實(shí)現(xiàn)
package sample.dw.paper.lucene.index;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import org.apache.lucene.analysis.Analyzer;
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.store.Directory;
import org.apache.lucene.store.FSDirectory;
import sample.dw.paper.lucene.util.HTMLDocParser;
/**
* This class is used to create an index for HTML files
*
*/
public class IndexManager {
//the directory that stores HTML files
private final String dataDir = "c:\\dataDir";
//the directory that is used to store a Lucene index
private final String indexDir = "c:\\indexDir";
/**
* create index
*/
public boolean createIndex() throws IOException{
if(true == ifIndexExist()){
return true;
}
File dir = new File(dataDir);
if(!dir.exists()){
return false;
}
File[] htmls = dir.listFiles();
Directory fsDirectory = FSDirectory.getDirectory(indexDir, true);
Analyzer analyzer = new StandardAnalyzer();
IndexWriter indexWriter = new IndexWriter(fsDirectory, analyzer, true);
for(int i = 0; i < htmls.length; i++){
String htmlPath = htmls[i].getAbsolutePath();
if(htmlPath.endsWith(".html") || htmlPath.endsWith(".htm")){
addDocument(htmlPath, indexWriter);
}
}
indexWriter.optimize();
indexWriter.close();
return true;
}
/**
* Add one document to the Lucene index
*/
public void addDocument(String htmlPath, IndexWriter indexWriter){
HTMLDocParser htmlParser = new HTMLDocParser(htmlPath);
String path = htmlParser.getPath();
String title = htmlParser.getTitle();
Reader content = htmlParser.getContent();
Document document = new Document();
document.add(new Field("path",path,Field.Store.YES,Field.Index.NO));
document.add(new Field("title",title,Field.Store.YES,Field.Index.TOKENIZED));
document.add(new Field("content",content));
try {
indexWriter.addDocument(document);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* judge if the index exists already
*/
public boolean ifIndexExist(){
File directory = new File(indexDir);
if(0 < directory.listFiles().length){
return true;
}else{
return false;
}
}
public String getDataDir(){
return this.dataDir;
}
public String getIndexDir(){
return this.indexDir;
}
}
|
這個類包含兩個私有屬性,分別是 dataDir
和 indexDir
。dataDir
代表存放等待進(jìn)行索引的 HTML 頁面的路徑,indexDir
代表了存放 Lucene 索引文件的路徑。類 IndexManager
提供了三個方法,分別是 createIndex
, addDocument
和 ifIndexExist
。如果索引不存在的話,你可以使用方法 createIndex
去創(chuàng)建一個新的索引,用方法 addDocument
去向一個索引上添加文檔。在我們的場景中,一個文檔就是一個 HTML 頁面。方法 addDocument
會調(diào)用由類 HTMLDocParser
提供的方法對 HTML 文檔進(jìn)行解析。你可以使用最后一個方法 ifIndexExist
來判斷 Lucene 的索引是否已經(jīng)存在。
現(xiàn)在我們來看一下放在包 sample.dw.paper.lucene.util
里面的類 HTMLDocParser
。這個類用來從 HTML 文件中提取出文本信息。這個類包含三個方法,分別是 getContent
,getTitle
和 getPath
。第一個方法返回去除了 HTML 標(biāo)記的文本內(nèi)容,第二個方法返回 HTML 文件的標(biāo)題,最后一個方法返回 HTML 文件的路徑。下面代碼給出了這個類的源代碼。
清單9:HTML 解析器
package sample.dw.paper.lucene.util;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import org.apache.lucene.demo.html.HTMLParser;
public class HTMLDocParser {
private String htmlPath;
private HTMLParser htmlParser;
public HTMLDocParser(String htmlPath){
this.htmlPath = htmlPath;
initHtmlParser();
}
private void initHtmlParser(){
InputStream inputStream = null;
try {
inputStream = new FileInputStream(htmlPath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if(null != inputStream){
try {
htmlParser = new HTMLParser(new InputStreamReader(inputStream, "utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
public String getTitle(){
if(null != htmlParser){
try {
return htmlParser.getTitle();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "";
}
public Reader getContent(){
if(null != htmlParser){
try {
return htmlParser.getReader();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public String getPath(){
return this.htmlPath;
}
}
|
5.在 Tomcat 5.0 上運(yùn)行應(yīng)用程序
現(xiàn)在我們可以在 Tomcat 5.0 上運(yùn)行開發(fā)好的應(yīng)用程序。
- 右鍵單擊 search.jsp,然后選擇 Run as > Run on Server,如下圖所示。
圖7:配置 Tomcat 5.0
- 在彈出的窗口中,選擇 Tomcat v5.0 Server 作為目標(biāo) Web 應(yīng)用程序服務(wù)器,然后點(diǎn)擊 Next,如下圖所示:
圖8:選擇 Tomcat 5.0
- 現(xiàn)在需要指定用來運(yùn)行 Web 應(yīng)用程序的 Apache Tomcat 5.0 以及 JRE 的路徑。這里你所選擇的 JRE 的版本必須和你用來編譯 Java 文件的 JRE 的版本一致。配置好之后,點(diǎn)擊 Finish。如下圖 所示。
圖9:完成Tomcat 5.0的配置
- 配置好之后,Tomcat 會自動運(yùn)行,并且會對 search.jsp 進(jìn)行編譯并顯示給用戶。如下圖 所示。
圖10:用戶界面
- 在輸入框中輸入關(guān)鍵詞 “information” 然后單擊 Search 按鈕。然后這個頁面上會顯示出搜索結(jié)果來,如下圖所示。
圖11:搜索結(jié)果
- 單擊搜索結(jié)果的第一個鏈接,頁面上就會顯示出所鏈接到的頁面的內(nèi)容。如下圖所示.
圖12:詳細(xì)信息
現(xiàn)在我們已經(jīng)成功的完成了示例項(xiàng)目的開發(fā),并成功的用Lucene實(shí)現(xiàn)了搜索和索引功能。你可以下載這個項(xiàng)目的源代碼(下載)。
總結(jié)
Lucene 提供了靈活的接口使我們更加方便的設(shè)計(jì)我們的 Web 搜索應(yīng)用程序。如果你想在你的應(yīng)用程序中加入搜索功能,那么 Lucene 是一個很好的選擇。在設(shè)計(jì)你的下一個帶有搜索功能的應(yīng)用程序的時候可以考慮使用 Lucene 來提供搜索功能。
本文摘自:http://www.ibm.com/developerworks/cn/web/wa-lucene2/
---------------------------------------------------------------------------------------------------------------------------------
說人之短,乃護(hù)己之短。夸己之長,乃忌人之長。皆由存心不厚,識量太狹耳。能去此弊,可以進(jìn)德,可以遠(yuǎn)怨。
http://m.tkk7.com/szhswl
------------------------------------------------------------------------------------------------------ ----------------- ---------
posted on 2007-12-17 19:17
宋針還 閱讀(267)
評論(0) 編輯 收藏 所屬分類:
搜索引擎