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

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

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

    隨筆-57  評(píng)論-117  文章-1  trackbacks-0

    什么是全文檢索與全文檢索系統(tǒng)?

    全文檢索是指計(jì)算機(jī)索引程序通過(guò)掃描文章中的每一個(gè)詞,對(duì)每一個(gè)詞建立一個(gè)索引,指明該詞在文章中出現(xiàn)的次數(shù)和位置,當(dāng)用戶查詢時(shí),檢索程序就根據(jù)事先建立的索引進(jìn)行查找,并將查找的結(jié)果反饋給用戶的檢索方式。這個(gè)過(guò)程類似于通過(guò)字典中的檢索字表查字的過(guò)程。

     

    全文檢索的方法主要分為按字檢索和按詞檢索兩種。按字檢索是指對(duì)于文章中的每一個(gè)字都建立索引,檢索時(shí)將詞分解為字的組合。對(duì)于各種不同的語(yǔ)言而言,字有不同的含義,比如英文中字與詞實(shí)際上是合一的,而中文中字與詞有很大分別。按詞檢索指對(duì)文章中的詞,即語(yǔ)義單位建立索引,檢索時(shí)按詞檢索,并且可以處理同義項(xiàng)等。

     

    全文檢索系統(tǒng)是按照全文檢索理論建立起來(lái)的用于提供全文檢索服務(wù)的軟件系統(tǒng)。一般來(lái)說(shuō),全文檢索需要具備建立索引和提供查詢的基本功能,此外現(xiàn)代的全文檢索系統(tǒng)還需要具有方便的用戶接口、面向WWW[1]的開(kāi)發(fā)接口、二次應(yīng)用開(kāi)發(fā)接口等等。功能上,全文檢索系統(tǒng)核心具有建立索引、處理查詢返回結(jié)果集、增加索引、優(yōu)化索引結(jié)構(gòu)等等功能,外圍則由各種不同應(yīng)用具有的功能組成。結(jié)構(gòu)上,全文檢索系統(tǒng)核心具有索引引擎、查詢引擎、文本分析引擎、對(duì)外接口等等,加上各種外圍應(yīng)用系統(tǒng)等等共同構(gòu)成了全文檢索系統(tǒng)。

     

    什么是Lucene?

    Lucene是apache軟件基金會(huì)jakarta項(xiàng)目組的一個(gè)子項(xiàng)目,是一個(gè)開(kāi)放源代碼的全文檢索引擎工具包,即它不是一個(gè)完整的全文檢索引擎,而是一個(gè)全文檢索引擎的架構(gòu),提供了完整的查詢引擎和索引引擎,部分文本分析引擎(英文與德文兩種西方語(yǔ)言)。Lucene的目的是為軟件開(kāi)發(fā)人員提供一個(gè)簡(jiǎn)單易用的工具包,以方便的在目標(biāo)系統(tǒng)中實(shí)現(xiàn)全文檢索的功能,或者是以此為基礎(chǔ)建立起完整的全文檢索引擎。

     

    Lucene的原作者是Doug Cutting,他是一位資深全文索引/檢索專家,曾經(jīng)是V-Twin搜索引擎的主要開(kāi)發(fā)者,后在Excite擔(dān)任高級(jí)系統(tǒng)架構(gòu)設(shè)計(jì)師,目前從事于一些Internet底層架構(gòu)的研究。早先發(fā)布在作者自己的http://www.lucene.com/,后來(lái)發(fā)布在SourceForge,2001年年底成為apache軟件基金會(huì)jakarta的一個(gè)子項(xiàng)目:http://jakarta.apache.org/lucene/

     

    Lucene作為一個(gè)全文檢索引擎,其具有如下突出的優(yōu)點(diǎn):

    (1)索引文件格式獨(dú)立于應(yīng)用平臺(tái)。Lucene定義了一套以8位字節(jié)為基礎(chǔ)的索引文件格式,使得兼容系統(tǒng)或者不同平臺(tái)的應(yīng)用能夠共享建立的索引文件。

    (2)在傳統(tǒng)全文檢索引擎的倒排索引的基礎(chǔ)上,實(shí)現(xiàn)了分塊索引,能夠針對(duì)新的文件建立小文件索引,提升索引速度。然后通過(guò)與原有索引的合并,達(dá)到優(yōu)化的目的。

    (3)優(yōu)秀的面向?qū)ο蟮南到y(tǒng)架構(gòu),使得對(duì)于Lucene擴(kuò)展的學(xué)習(xí)難度降低,方便擴(kuò)充新功能。

    (4)設(shè)計(jì)了獨(dú)立于語(yǔ)言和文件格式的文本分析接口,索引器通過(guò)接受Token流完成索引文件的創(chuàng)立,用戶擴(kuò)展新的語(yǔ)言和文件格式,只需要實(shí)現(xiàn)文本分析的接口。

    (5)已經(jīng)默認(rèn)實(shí)現(xiàn)了一套強(qiáng)大的查詢引擎,用戶無(wú)需自己編寫(xiě)代碼即使系統(tǒng)可獲得強(qiáng)大的查詢能力,Lucene的查詢實(shí)現(xiàn)中默認(rèn)實(shí)現(xiàn)了布爾操作、模糊查詢(Fuzzy Search)、分組查詢等等。

     

    面對(duì)已經(jīng)存在的商業(yè)全文檢索引擎,Lucene也具有相當(dāng)?shù)膬?yōu)勢(shì):

    首先,它的開(kāi)發(fā)源代碼發(fā)行方式(遵守Apache Software License),在此基礎(chǔ)上程序員不僅僅可以充分的利用Lucene所提供的強(qiáng)大功能,而且可以深入細(xì)致的學(xué)習(xí)到全文檢索引擎制作技術(shù)和面相對(duì)象編程的實(shí)踐,進(jìn)而在此基礎(chǔ)上根據(jù)應(yīng)用的實(shí)際情況編寫(xiě)出更好的更適合當(dāng)前應(yīng)用的全文檢索引擎。在這一點(diǎn)上,商業(yè)軟件的靈活性遠(yuǎn)遠(yuǎn)不及Lucene。

    其次,Lucene秉承了開(kāi)放源代碼一貫的架構(gòu)優(yōu)良的優(yōu)勢(shì),設(shè)計(jì)了一個(gè)合理而極具擴(kuò)充能力的面向?qū)ο蠹軜?gòu),程序員可以在Lucene的基礎(chǔ)上擴(kuò)充各種功能,比如擴(kuò)充中文處理能力,從文本擴(kuò)充到HTML、PDF等等文本格式的處理,編寫(xiě)這些擴(kuò)展的功能不僅僅不復(fù)雜,而且由于Lucene恰當(dāng)合理的對(duì)系統(tǒng)設(shè)備做了程序上的抽象,擴(kuò)展的功能也能輕易的達(dá)到跨平臺(tái)的能力。

    最后,轉(zhuǎn)移到apache軟件基金會(huì)后,借助于apache軟件基金會(huì)的網(wǎng)絡(luò)平臺(tái),程序員可以方便的和開(kāi)發(fā)者、其它程序員交流,促成資源的共享,甚至直接獲得已經(jīng)編寫(xiě)完備的擴(kuò)充功能。最后,雖然Lucene使用Java語(yǔ)言寫(xiě)成,但是開(kāi)放源代碼社區(qū)的程序員正在不懈的將之使用各種傳統(tǒng)語(yǔ)言實(shí)現(xiàn)(例如.net framework),在遵守Lucene索引文件格式的基礎(chǔ)上,使得Lucene能夠運(yùn)行在各種各樣的平臺(tái)上,系統(tǒng)管理員可以根據(jù)當(dāng)前的平臺(tái)適合的語(yǔ)言來(lái)合理的選。

     

    索引和搜索的關(guān)系

    索引是現(xiàn)代搜索引擎的核心,建立索引的過(guò)程就是把源數(shù)據(jù)處理成非常方便查詢的索引文件的過(guò)程。為什么索引這么重要呢,試想你現(xiàn)在要在大量的文檔中搜索含有某個(gè)關(guān)鍵詞的文檔,那么如果不建立索引的話你就需要把這些文檔順序的讀入內(nèi)存,然后檢查這個(gè)文章中是不是含有要查找的關(guān)鍵詞,這樣的話就會(huì)耗費(fèi)非常多的時(shí)間,想想搜索引擎可是在毫秒級(jí)的時(shí)間內(nèi)查找出要搜索的結(jié)果的。這就是由于建立了索引的原因,你可以把索引想象成這樣一種數(shù)據(jù)結(jié)構(gòu),他能夠使你快速的隨機(jī)訪問(wèn)存儲(chǔ)在索引中的關(guān)鍵詞,進(jìn)而找到該關(guān)鍵詞所關(guān)聯(lián)的文檔。Lucene 采用的是一種稱為反向索引(inverted index)的機(jī)制。反向索引就是說(shuō)我們維護(hù)了一個(gè)詞/短語(yǔ)表,對(duì)于這個(gè)表中的每個(gè)詞/短語(yǔ),都有一個(gè)鏈表描述了有哪些文檔包含了這個(gè)詞/短語(yǔ)。這樣在用戶輸入查詢條件的時(shí)候,就能非常快的得到搜索結(jié)果。我們將在本系列文章的第二部分詳細(xì)介紹 Lucene 的索引機(jī)制,由于 Lucene 提供了簡(jiǎn)單易用的 API,所以即使讀者剛開(kāi)始對(duì)全文本進(jìn)行索引的機(jī)制并不太了解,也可以非常容易的使用 Lucene 對(duì)你的文檔實(shí)現(xiàn)索引。

    對(duì)文檔建立好索引后,就可以在這些索引上面進(jìn)行搜索了。搜索引擎首先會(huì)對(duì)搜索的關(guān)鍵詞進(jìn)行解析,然后再在建立好的索引上面進(jìn)行查找,最終返回和用戶輸入的關(guān)鍵詞相關(guān)聯(lián)的文檔。

     

    Lucene 軟件包分析

    Package: org.apache.lucene.document

    這個(gè)包提供了一些為封裝要索引的文檔所需要的類,比如 Document, Field。這樣,每一個(gè)文檔最終被封裝成了一個(gè) Document 對(duì)象。

    Package: org.apache.lucene.analysis

    這個(gè)包主要功能是對(duì)文檔進(jìn)行分詞,因?yàn)槲臋n在建立索引之前必須要進(jìn)行分詞,所以這個(gè)包的作用可以看成是為建立索引做準(zhǔn)備工作。

    Package: org.apache.lucene.index

    這個(gè)包提供了一些類來(lái)協(xié)助創(chuàng)建索引以及對(duì)創(chuàng)建好的索引進(jìn)行更新。這里面有兩個(gè)基礎(chǔ)的類:IndexWriter 和 IndexReader,其中 IndexWriter 是用來(lái)創(chuàng)建索引并添加文檔到索引中的,IndexReader 是用來(lái)刪除索引中的文檔的。

    Package: org.apache.lucene.search

    這個(gè)包提供了對(duì)在建立好的索引上進(jìn)行搜索所需要的類。比如 IndexSearcher 和 Hits, IndexSearcher 定義了在指定的索引上進(jìn)行搜索的方法,Hits 用來(lái)保存搜索得到的結(jié)果

    Lucene包結(jié)構(gòu)功能表

    包名

    功能

    org.apache.lucene.analysis

    語(yǔ)言分析器,主要用于的切詞,支持中文主要是擴(kuò)展此類

    org.apache.lucene.document

    索引存儲(chǔ)時(shí)的文檔結(jié)構(gòu)管理,類似于關(guān)系型數(shù)據(jù)庫(kù)的表結(jié)構(gòu)

    org.apache.lucene.index

    索引管理,包括索引建立、刪除等

    org.apache.lucene.queryParser

    查詢分析器,實(shí)現(xiàn)查詢關(guān)鍵詞間的運(yùn)算,如與、或、非等

    org.apache.lucene.search

    檢索管理,根據(jù)查詢條件,檢索得到結(jié)果

    org.apache.lucene.store

    數(shù)據(jù)存儲(chǔ)管理,主要包括一些底層的I/O操作

    org.apache.lucene.util

    一些公用類

     

    一個(gè)簡(jiǎn)單的搜索應(yīng)用程序

    假設(shè)我們的電腦的目錄中含有很多文本文檔,我們需要查找哪些文檔含有某個(gè)關(guān)鍵詞。為了實(shí)現(xiàn)這種功能,我們首先利用

    Lucene 對(duì)這個(gè)目錄中的文檔建立索引,然后在建立好的索引中搜索我們所要查找的文檔。通過(guò)這個(gè)例子讀者會(huì)對(duì)如何利用

    Lucene 構(gòu)建自己的搜索應(yīng)用程序有個(gè)比較清楚的認(rèn)識(shí)。

     

    建立索引

    為了對(duì)文檔進(jìn)行索引,Lucene 提供了五個(gè)基礎(chǔ)的類,他們分別是 Document, Field, IndexWriter, Analyzer, Directory。下面我們分別介紹一下這五個(gè)類的用途:

     

    Document

    Document 是用來(lái)描述文檔的,這里的文檔可以指一個(gè) HTML 頁(yè)面,一封電子郵件,或者是一個(gè)文本文件。一個(gè) Document 對(duì)象由多個(gè) Field 對(duì)象組成的。可以把一個(gè) Document 對(duì)象想象成數(shù)據(jù)庫(kù)中的一個(gè)記錄,而每個(gè) Field 對(duì)象就是記錄的一個(gè)字段。

    接口名

    備注

    add(Field field)

    添加一個(gè)字段(Field)到Document中

    String get(String name)

    從文檔中獲得一個(gè)字段對(duì)應(yīng)的文本

    Field getField(String name)

    由字段名獲得字段值

    Field[] getFields(String name)

    由字段名獲得字段值的集

     

    Field

    Field 對(duì)象是用來(lái)描述一個(gè)文檔的某個(gè)屬性的,比如一封電子郵件的標(biāo)題和內(nèi)容可以用兩個(gè) Field 對(duì)象分別描述。

    即上文所說(shuō)的“字段”,它是Document的片段section。

    Field的構(gòu)造函數(shù):

    Field(String name, String string, boolean store, boolean index, boolean token)。

    Indexed:如果字段是Indexed的,表示這個(gè)字段是可檢索的。

    Stored:如果字段是Stored的,表示這個(gè)字段的值可以從檢索結(jié)果中得到。

    Tokenized:如果一個(gè)字段是Tokenized的,表示它是有經(jīng)過(guò)Analyzer轉(zhuǎn)變后成為一個(gè)tokens序列,在這個(gè)轉(zhuǎn)變過(guò)程tokenization中,Analyzer提取出需要進(jìn)行索引的文本,而剔除一些冗余的詞句(例如:a,the,they等,詳見(jiàn)org.apache.lucene.analysis.StopAnalyzer.ENGLISH_STOP_WORDS和org.apache.lucene.analysis.standard.StandardAnalyzer(String[] stopWords)的API)。Token是索引時(shí)候的基本單元,代表一個(gè)被索引的詞,例如一個(gè)英文單詞,或者一個(gè)漢字。因此,所有包含中文的文本都必須是Tokenized的。

     

    Analyzer

    在一個(gè)文檔被索引之前,首先需要對(duì)文檔內(nèi)容進(jìn)行分詞處理,這部分工作就是由 Analyzer 來(lái)做的。Analyzer 類是一個(gè)抽象類,它有多個(gè)實(shí)現(xiàn)。針對(duì)不同的語(yǔ)言和應(yīng)用需要選擇適合的 Analyzer。Analyzer 把分詞后的內(nèi)容交給 IndexWriter 來(lái)建立索引。

    接口名

    備注

    addDocument(Document doc)

    索引添加一個(gè)文檔

    addIndexes(Directory[] dirs)

    將目錄中已存在索引添加到這個(gè)索引

    addIndexes(IndexReader[] readers)

    將提供的索引添加到這個(gè)索引

    optimize()

    合并索引并優(yōu)化

    close()

    關(guān)閉

    IndexWriter

    IndexWriter 是 Lucene 用來(lái)創(chuàng)建索引的一個(gè)核心的類,他的作用是把一個(gè)個(gè)的 Document 對(duì)象加到索引中來(lái)。

     

    Directory

    這個(gè)類代表了 Lucene 的索引的存儲(chǔ)的位置,這是一個(gè)抽象類,它目前有兩個(gè)實(shí)現(xiàn),第一個(gè)是 FSDirectory,它表示一個(gè)存儲(chǔ)在文件系統(tǒng)中的索引的位置。第二個(gè)是 RAMDirectory,它表示一個(gè)存儲(chǔ)在內(nèi)存當(dāng)中的索引的位置。

    熟悉了建立索引所需要的這些類后,我們就開(kāi)始對(duì)某個(gè)目錄下面的文本文件建立索引了,給出了對(duì)某個(gè)目錄下的文本文件建立索引的源代碼。

    public class TextFileIndexer {
        public static void main(String[] args) throws Exception {
            // fileDir is the directory that contains the text files to be indexed
            File fileDir = new File("C:\\index");
     
            // indexDir is the directory that hosts Lucene's index files
            File indexDir = new File("C:\\luceneIndex");
            Analyzer luceneAnalyzer = new StandardAnalyzer(Version.LUCENE_30);
            IndexWriter indexWriter = new IndexWriter(FSDirectory.open(indexDir), luceneAnalyzer, true, IndexWriter.MaxFieldLength.LIMITED);
            File[] textFiles = fileDir.listFiles();
            long startTime = new Date().getTime();
     
            // Add documents to the index
            for (int i = 0; i < textFiles.length; i++) {
                if (textFiles[i].isFile() && textFiles[i].getName().endsWith(".txt")) {
                    System.out.println("File " + textFiles[i].getCanonicalPath() + " is being indexed");
                    Reader textReader = new FileReader(textFiles[i]);
                    Document document = new Document();
     
                    document.add(new Field("content", textReader));
                    document.add(new Field("path", textFiles[i].getPath(), Field.Store.YES, Field.Index.ANALYZED_NO_NORMS));
                    indexWriter.addDocument(document);
                }
            }
     
            indexWriter.optimize();
            indexWriter.close();
            long endTime = new Date().getTime();
     
            System.out.println("It took " + (endTime - startTime) + " milliseconds to create an index for the files in the directory " + fileDir.getPath());
        }
    }

     

    我們注意到類 IndexWriter 的構(gòu)造函數(shù)需要三個(gè)參數(shù),第一個(gè)參數(shù)指定了所創(chuàng)建的索引要存放的位置,他可以是一個(gè) File 對(duì)象,也可以是一個(gè) FSDirectory 對(duì)象或者 RAMDirectory 對(duì)象。第二個(gè)參數(shù)指定了 Analyzer 類的一個(gè)實(shí)現(xiàn),也就是指定這個(gè)索引是用哪個(gè)分詞器對(duì)文擋內(nèi)容進(jìn)行分詞。第三個(gè)參數(shù)是一個(gè)布爾型的變量,如果為 true 的話就代表創(chuàng)建一個(gè)新的索引,為 false 的話就代表在原來(lái)索引的基礎(chǔ)上進(jìn)行操作。接著程序遍歷了目錄下面的所有文本文檔,并為每一個(gè)文本文檔創(chuàng)建了一個(gè) Document 對(duì)象。然后把文本文檔的兩個(gè)屬性:路徑和內(nèi)容加入到了兩個(gè) Field 對(duì)象中,接著在把這兩個(gè) Field 對(duì)象加入到 Document 對(duì)象中,最后把這個(gè)文檔用 IndexWriter 類的 add 方法加入到索引中去。這樣我們便完成了索引的創(chuàng)建。接下來(lái)我們進(jìn)入在建立好的索引上進(jìn)行搜索的部分。

     

    搜索文檔

     

    Query

    這是一個(gè)抽象類,他有多個(gè)實(shí)現(xiàn),比如TermQuery, BooleanQuery, PrefixQuery. 這個(gè)類的目的是把用戶輸入的查詢字符串封裝成Lucene能夠識(shí)別的Query。

    Term

    Term是搜索的基本單位,一個(gè)Term對(duì)象有兩個(gè)String類型的域組成。生成一個(gè)Term對(duì)象可以有如下一條語(yǔ)句來(lái)完成:Term term = new Term(“fieldName”,”queryWord”); 其中第一個(gè)參數(shù)代表了要在文檔的哪一個(gè)Field上進(jìn)行查找,第二個(gè)參數(shù)代表了要查詢的關(guān)鍵詞。

    TermQuery

    TermQuery是抽象類Query的一個(gè)子類,它同時(shí)也是Lucene支持的最為基本的一個(gè)查詢類。生成一個(gè)TermQuery對(duì)象由如下語(yǔ)句完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的構(gòu)造函數(shù)只接受一個(gè)參數(shù),那就是一個(gè)Term對(duì)象。

    IndexSearcher

    IndexSearcher是用來(lái)在建立好的索引上進(jìn)行搜索的。它只能以只讀的方式打開(kāi)一個(gè)索引,所以可以有多個(gè)IndexSearcher的實(shí)例在一個(gè)索引上進(jìn)行操作。

    Hits

    Hits是用來(lái)保存搜索的結(jié)果的。

     

    介紹完這些搜索所必須的類之后,我們就開(kāi)始在之前所建立的索引上進(jìn)行搜索了,清單2給出了完成搜索功能所需要的代碼。

    如何添加一個(gè)文檔到索引文

    Document document = new Document();

    document.add(new Field("content",textReader));

    document.add(new Field("path",textFiles[i].getPath(), Field.Store.YES, Field.Index.ANALYZED_NO_NORMS));

    indexWriter.addDocument(document);

    //最后不要忘記了關(guān)閉

    indexWriter.close();

    首先第一行創(chuàng)建了類 Document 的一個(gè)實(shí)例,它由一個(gè)或者多個(gè)的域(Field)組成。你可以把這個(gè)類想象成代表了一個(gè)實(shí)際的文檔,比如一個(gè) HTML 頁(yè)面,一個(gè) PDF 文檔,或者一個(gè)文本文件。而類 Document 中的域一般就是實(shí)際文檔的一些屬性。比如對(duì)于一個(gè) HTML 頁(yè)面,它的域可能包括標(biāo)題,內(nèi)容,URL 等。我們可以用不同類型的 Field 來(lái)控制文檔的哪些內(nèi)容應(yīng)該索引,哪些內(nèi)容應(yīng)該存儲(chǔ)。如果想獲取更多的關(guān)于 Lucene 的域的信息,可以參考 Lucene 的幫助文檔。代碼的第二行和第三行為文檔添加了兩個(gè)域,每個(gè)域包含兩個(gè)屬性,分別是域的名字和域的內(nèi)容。在我們的例子中兩個(gè)域的名字分別是"content"和"path"。分別存儲(chǔ)了我們需要索引的文本文件的內(nèi)容和路徑。最后一行把準(zhǔn)備好的文檔添加到了索引當(dāng)中。

     

    從索引中刪除文檔

    類IndexReader負(fù)責(zé)從一個(gè)已經(jīng)存在的索引中刪除文檔。

    File indexDir = new File("C:\\luceneIndex");

    IndexReader ir = IndexReader.open(indexDir);

    ir.delete(1);

    ir.delete(new Term("path","C:\\file_to_index\lucene.txt"));

    ir.close();

    第二行用靜態(tài)方法 IndexReader.open(indexDir) 初始化了類 IndexReader 的一個(gè)實(shí)例,這個(gè)方法的參數(shù)指定了索引的存儲(chǔ)路徑。類 IndexReader 提供了兩種方法去刪除一個(gè)文檔,如程序中的第三行和第四行所示。第三行利用文檔的編號(hào)來(lái)刪除文檔。每個(gè)文檔都有一個(gè)系統(tǒng)自動(dòng)生成的編號(hào)。第四行刪除了路徑為"C:\\file_to_index\lucene.txt"的文檔。你可以通過(guò)指定文件路徑來(lái)方便的刪除一個(gè)文檔。值得注意的是雖然利用上述代碼刪除文檔使得該文檔不能被檢索到,但是并沒(méi)有物理上刪除該文檔。Lucene 只是通過(guò)一個(gè)后綴名為 .delete 的文件來(lái)標(biāo)記哪些文檔已經(jīng)被刪除。既然沒(méi)有物理上刪除,我們可以方便的把這些標(biāo)記為刪除的文檔恢復(fù)過(guò)來(lái),如清單 3 所示,首先打開(kāi)一個(gè)索引,然后調(diào)用方法 ir.undeleteAll() 來(lái)完成恢復(fù)工作。

     

    恢復(fù)已刪除文檔

    File indexDir = new File("C:\\luceneIndex");

    IndexReader ir = IndexReader.open(indexDir);

    ir.undeleteAll();

    ir.close();

     

    如何物理上刪除文檔

    File indexDir = new File("C:\\luceneIndex");

    Analyzer luceneAnalyzer = new StandardAnalyzer();

    IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,false);

    indexWriter.optimize();

    indexWriter.close();

    第三行創(chuàng)建了類 IndexWriter 的一個(gè)實(shí)例,并且打開(kāi)了一個(gè)已經(jīng)存在的索引。第 4 行對(duì)索引進(jìn)行清理,清理過(guò)程中將把所有標(biāo)記為刪除的文檔物理刪除。

     

    提高索引性能

    利用 Lucene,在創(chuàng)建索引的工程中你可以充分利用機(jī)器的硬件資源來(lái)提高索引的效率。當(dāng)你需要索引大量的文件時(shí),你會(huì)注意到索引過(guò)程的瓶頸是在往磁盤(pán)上寫(xiě)索引文件的過(guò)程中。為了解決這個(gè)問(wèn)題, Lucene 在內(nèi)存中持有一塊緩沖區(qū)。但我們?nèi)绾慰刂?Lucene 的緩沖區(qū)呢?幸運(yùn)的是,Lucene 的類 IndexWriter 提供了三個(gè)參數(shù)用來(lái)調(diào)整緩沖區(qū)的大小以及往磁盤(pán)上寫(xiě)索引文件的頻率。

    1.合并因子(mergeFactor)

    這個(gè)參數(shù)決定了在 Lucene 的一個(gè)索引塊中可以存放多少文檔以及把磁盤(pán)上的索引塊合并成一個(gè)大的索引塊的頻率。比如,如果合并因子的值是 10,那么當(dāng)內(nèi)存中的文檔數(shù)達(dá)到 10 的時(shí)候所有的文檔都必須寫(xiě)到磁盤(pán)上的一個(gè)新的索引塊中。并且,如果磁盤(pán)上的索引塊的隔數(shù)達(dá)到 10 的話,這 10 個(gè)索引塊會(huì)被合并成一個(gè)新的索引塊。這個(gè)參數(shù)的默認(rèn)值是 10,如果需要索引的文檔數(shù)非常多的話這個(gè)值將是非常不合適的。對(duì)批處理的索引來(lái)講,為這個(gè)參數(shù)賦一個(gè)比較大的值會(huì)得到比較好的索引效果。

    2.最小合并文檔數(shù)

    這個(gè)參數(shù)也會(huì)影響索引的性能。它決定了內(nèi)存中的文檔數(shù)至少達(dá)到多少才能將它們寫(xiě)回磁盤(pán)。這個(gè)參數(shù)的默認(rèn)值是10,如果你有足夠的內(nèi)存,那么將這個(gè)值盡量設(shè)的比較大一些將會(huì)顯著的提高索引性能。

    3.最大合并文檔數(shù)

    這個(gè)參數(shù)決定了一個(gè)索引塊中的最大的文檔數(shù)。它的默認(rèn)值是 Integer.MAX_VALUE,將這個(gè)參數(shù)設(shè)置為比較大的值可以提高索引效率和檢索速度,由于該參數(shù)的默認(rèn)值是整型的最大值,所以我們一般不需要改動(dòng)這個(gè)參數(shù)。

    int mergeFactor = 10;

    int minMergeDocs = 10;

    int maxMergeDocs = Integer.MAX_VALUE;

    IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);

    indexWriter.mergeFactor = mergeFactor;

    indexWriter.minMergeDocs = minMergeDocs;

    indexWriter.maxMergeDocs = maxMergeDocs;

    下面我們來(lái)看一下這三個(gè)參數(shù)取不同的值對(duì)索引時(shí)間的影響,注意參數(shù)值的不同和索引之間的關(guān)系。我們?yōu)檫@個(gè)實(shí)驗(yàn)準(zhǔn)備了 10000 個(gè)測(cè)試文檔。表 1 顯示了測(cè)試結(jié)果。

    1:測(cè)試結(jié)果
    clip_image001

    通過(guò)表 1,你可以清楚地看到三個(gè)參數(shù)對(duì)索引時(shí)間的影響。在實(shí)踐中,你會(huì)經(jīng)常的改變合并因子和最小合并文檔數(shù)的值來(lái)提高索引性能。只要你有足夠大的內(nèi)存,你可以為合并因子和最小合并文檔數(shù)這兩個(gè)參數(shù)賦盡量大的值以提高索引效率,另外我們一般無(wú)需更改最大合并文檔數(shù)這個(gè)參數(shù)的值,因?yàn)橄到y(tǒng)已經(jīng)默認(rèn)將它設(shè)置成了最大。



    作者:hoojo
    出處:
    blog:http://blog.csdn.net/IBM_hoojo
             http://hoojo.cnblogs.com
    本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。


    版權(quán)所有,轉(zhuǎn)載請(qǐng)注明出處 本文出自:
    分享道版權(quán)所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處,謝謝
    posted on 2012-09-05 12:21 hoojo 閱讀(2180) 評(píng)論(0)  編輯  收藏 所屬分類: JavaEEJavaSEOthersSE FTS
    主站蜘蛛池模板: 亚洲国产精品线观看不卡| 中文字幕无码精品亚洲资源网久久 | 日韩免费视频在线观看| 国产AV无码专区亚洲AWWW| 亚洲人成电影院在线观看| 一级做a爰全过程免费视频毛片| 8x8x华人永久免费视频| 免费观看日本污污ww网站一区| 久久国产亚洲电影天堂| 小说专区亚洲春色校园| 在线美女免费观看网站h| 免费a级黄色毛片| 亚洲日产2021三区| 国产无遮挡色视频免费观看性色| 在线看片v免费观看视频777| 精品国产人成亚洲区| 亚洲高清一区二区三区| 女同免费毛片在线播放| 国产免费观看a大片的网站| 亚洲精品自拍视频| www在线观看免费视频| 成人人免费夜夜视频观看| 日韩亚洲一区二区三区| 边摸边吃奶边做爽免费视频99 | 亚洲Av无码国产情品久久 | 国产a不卡片精品免费观看| 亚洲五月激情综合图片区| 成人免费视频一区二区| 无人影院手机版在线观看免费| 亚洲日产韩国一二三四区| 国产精品无码亚洲一区二区三区| 亚洲黄色免费观看| 国产亚洲精品国产| 免费无码婬片aaa直播表情| 最近中文字幕无吗免费高清 | 亚洲精品麻豆av| 亚洲精品无码少妇30P| 最近中文字幕免费mv在线视频| 亚洲综合熟女久久久30p| 亚洲日韩在线中文字幕综合| 成人免费一级毛片在线播放视频 |