<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    szhswl
    宋針還的個人空間
    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)
    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)行。例如,如果索引的文檔包含兩個域,TitleContent,你就可以使用查詢 “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)境:

    1. Eclipse 集成開發(fā)環(huán)境
    2. Tomcat 5.0
    3. Lucene Library
    4. 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)目

    1. 在 Eclipse 里面,選擇 File > New > Project,然后再彈出的窗口中選擇動態(tài) Web 項(xiàng)目,如下圖所示。

    圖二:創(chuàng)建動態(tài)Web項(xiàng)目
    創(chuàng)建動態(tài)Web項(xiàng)目
    1. 在創(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)
    動態(tài) Web 項(xiàng)目的結(jié)構(gòu)

    2. 設(shè)計(jì) Web 項(xiàng)目的架構(gòu)

    在我們的設(shè)計(jì)中,把該系統(tǒng)分成如下四個子系統(tǒng):

    1. 用戶接口: 這個子系統(tǒng)提供用戶界面使用戶可以向 Web 應(yīng)用程序服務(wù)器提交搜索請求,然后搜索結(jié)果通過用戶接口來顯示出來。我們用一個名為 search.jsp 的頁面來實(shí)現(xiàn)該子系統(tǒng)。
    2. 請求管理器: 這個子系統(tǒng)管理從客戶端發(fā)送過來的搜索請求并把搜索請求分發(fā)到搜索子系統(tǒng)中。最后搜索結(jié)果從搜索子系統(tǒng)返回并最終發(fā)送到用戶接口子系統(tǒng)。我們使用一個 Servlet 來實(shí)現(xiàn)這個子系統(tǒng)。
    3. 搜索子系統(tǒng): 這個子系統(tǒng)負(fù)責(zé)在索引文件上進(jìn)行搜索并把搜索結(jié)構(gòu)傳遞給請求管理器。我們使用 Lucene 提供的 API 來實(shí)現(xiàn)該子系統(tǒng)。
    4. 索引子系統(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)中,它包含了兩個類,SearchManagerSearchResultBean,第一個類用來實(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 提供的方法 getTitlegetContent 來對 HTML 頁面進(jìn)行解析。


    圖四:項(xiàng)目的架構(gòu)設(shè)計(jì)
    項(xiàng)目的架構(gòu)設(shè)計(jì)

    3. 子系統(tǒng)的實(shí)現(xiàn)

    在分析了系統(tǒng)的架構(gòu)設(shè)計(jì)之后,我們接下來看系統(tǒng)實(shí)現(xiàn)的詳細(xì)信息。

    1. 用戶接口: 這個子系統(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ù)器提交搜索請求
    向Web服務(wù)器提交搜索請求

    這個JSP的第二部分負(fù)責(zé)顯示搜索結(jié)果給用戶,如圖下圖所示:


    圖6:顯示搜索結(jié)果
    顯示搜索結(jié)果
    1. 請求管理器: 一個名為 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é)果被返回到客戶端。

    1. 搜索子系統(tǒng): 在這個子系統(tǒng)中,我們定義了兩個類:SearchManagerSearchResultBean。第一個類用來實(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 中,含有兩個屬性,分別是 htmlPathhtmlTitle,以及這個兩個屬性的 get 和 set 方法。這也意味著我們的搜索結(jié)果包含兩個屬性:htmlPathhtmlTitle,其中 htmlPath 代表了 HTML 文件的路徑,htmlTitle 代表了 HTML 文件的標(biāo)題。

    1. 索引子系統(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;
                }
                }
                

    這個類包含兩個私有屬性,分別是 dataDirindexDirdataDir 代表存放等待進(jìn)行索引的 HTML 頁面的路徑,indexDir 代表了存放 Lucene 索引文件的路徑。類 IndexManager 提供了三個方法,分別是 createIndex, addDocumentifIndexExist。如果索引不存在的話,你可以使用方法 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 文件中提取出文本信息。這個類包含三個方法,分別是 getContentgetTitlegetPath。第一個方法返回去除了 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)用程序。

    1. 右鍵單擊 search.jsp,然后選擇 Run as > Run on Server,如下圖所示。

    圖7:配置 Tomcat 5.0
    配置 Tomcat 5.0
    1. 在彈出的窗口中,選擇 Tomcat v5.0 Server 作為目標(biāo) Web 應(yīng)用程序服務(wù)器,然后點(diǎn)擊 Next,如下圖所示:

    圖8:選擇 Tomcat 5.0
    選擇 Tomcat 5.0
    1. 現(xiàn)在需要指定用來運(yùn)行 Web 應(yīng)用程序的 Apache Tomcat 5.0 以及 JRE 的路徑。這里你所選擇的 JRE 的版本必須和你用來編譯 Java 文件的 JRE 的版本一致。配置好之后,點(diǎn)擊 Finish。如下圖 所示。

    圖9:完成Tomcat 5.0的配置
    完成Tomcat 5.0的配置
    1. 配置好之后,Tomcat 會自動運(yùn)行,并且會對 search.jsp 進(jìn)行編譯并顯示給用戶。如下圖 所示。

    圖10:用戶界面
    用戶界面
    1. 在輸入框中輸入關(guān)鍵詞 “information” 然后單擊 Search 按鈕。然后這個頁面上會顯示出搜索結(jié)果來,如下圖所示。

    圖11:搜索結(jié)果
    搜索結(jié)果
    1. 單擊搜索結(jié)果的第一個鏈接,頁面上就會顯示出所鏈接到的頁面的內(nèi)容。如下圖所示.

    圖12:詳細(xì)信息
    詳細(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://www.tkk7.com/szhswl
    ------------------------------------------------------------------------------------------------------ ----------------- ---------
    posted on 2007-12-17 19:17 宋針還 閱讀(267) 評論(0)  編輯  收藏 所屬分類: 搜索引擎
    主站蜘蛛池模板: 亚洲第一页在线观看| 国产亚洲精品成人a v小说| 久久亚洲国产精品成人AV秋霞| 九九久久国产精品免费热6| 亚洲国产精品无码久久久久久曰| 亚洲av成人无码网站…| 国产免费131美女视频| 国产成人久久精品亚洲小说| 国产精品久免费的黄网站| 亚洲爆乳大丰满无码专区| 国产成人无码区免费A∨视频网站 国产成人涩涩涩视频在线观看免费 | 精品成人免费自拍视频| 亚洲国产成人私人影院| 一区二区三区观看免费中文视频在线播放 | 免费无码一区二区| 亚洲高清免费视频| 视频免费在线观看| 亚洲国产成人精品久久 | 韩国免费A级毛片久久| 亚洲国产成人片在线观看无码| 男人j进入女人j内部免费网站| 77777_亚洲午夜久久多人| 大学生一级毛片免费看| 相泽南亚洲一区二区在线播放| 亚洲区不卡顿区在线观看| 毛片在线全部免费观看| 亚洲喷奶水中文字幕电影| 国产成人免费全部网站| 国产成人自产拍免费视频| 亚洲视频在线视频| 韩国二级毛片免费播放| 国产免费牲交视频免费播放| 77777_亚洲午夜久久多人| 四虎影在线永久免费四虎地址8848aa| eeuss影院www天堂免费| 亚洲成综合人影院在院播放| 一本色道久久88亚洲综合 | 国产成人亚洲综合a∨| 亚洲V无码一区二区三区四区观看| 青青青国产在线观看免费| 免费精品国产自产拍在线观看|